Python custom log to database - python

I have the following sample Python code, and when I try to execute, am getting mysql error message. Context, am trying to create custom logs, log the messages, insert to a MySql table for analysis. Providing relevant portions for mysql execute.
levelnum= str(record.levelno) # 40
levelname=str(record.levelname) # ERROR
msg=str(self.log_msg) # "This error occurred: This is test message"
createtime=str(tm) #2018-06-26 03:43:47
record.name = 'MY_LOGGER'
sql = 'INSERT INTO emp.log (log_level, log_levelname, log, created_at, created_by) VALUES ('+levelnum+ ', '+levelname+ ', '+msg+ ', '+createtime+ ', '+record.name+')'
Error message: ProgrammingError: (1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'error msg, 2018-06-26 03:43:47, MY_LOGGER)' at line 1")
Am using mysql, and trying to insert to the table as follows:
try:
self.sql_cursor.execute(sql)
self.sql_conn.commit()
except pymysql.InternalError as e:
print e
print 'CRITICAL DB ERROR! Logging to database not possible!'
I think, am missing some formatting while passing parameters in the SQL query, but couldn't get the correct one.
Appreciate if someone can help fix this.

You are not quoting the timestamp, hence the error.
Rather than trying to quote the values manually, use the built-in quoting functionality provided by pymysql as part of the DBI interface.
sql = 'INSERT INTO `emp.log` (`log_level`, `log_levelname`, `log`, `created_at`, `created_by`) VALUES (%s, %s, %s, %s, %s)'
self.cursor.execute(sql, (levelnum, levelname, msg, createtime, record.name))

Related

Use table names as sql parameters in python [duplicate]

I have a syntax error in my python which which stops MySQLdb from inserting into my database. The SQL insert is below.
cursor.execute("INSERT INTO %s (description, url) VALUES (%s, %s);", (table_name.encode("utf-8"), key.encode("utf-8"), data[key].encode("utf-8")))
I get the following error in my stack trace.
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your
SQL syntax; check the manual that corresponds to your MariaDB server
version for the right syntax to use near ''four' (description, url) VALUES ('', 'http://imgur.com/a/V8sdH')' at line 1")
I would really appreciate assistance as I cannot figure this out.
EDIT:
Fixed it with the following line:
cursor.execute("INSERT INTO " + table_name + " (description, url) VALUES (%s, %s);", (key.encode("utf-8"), data[key].encode("utf-8")))
Not the most sophisticated, but I hope to use it as a jumping off point.
It looks like this is your SQL statement:
cursor.execute("INSERT INTO %s (description, url) VALUES (%s, %s);", (table_name.encode("utf-8"), key.encode("utf-8"), data[key].encode("utf-8")))
IIRC, the name of the table is not able to be parameterized (because it gets quoted improperly). You'll need to inject that into the string some other way (preferably safely -- by checking that the table name requested matches a whitelisted set of table names)... e.g.:
_TABLE_NAME_WHITELIST = frozenset(['four'])
...
if table_name not in _TABLE_NAME_WHITELIST:
raise Exception('Probably better to define a specific exception for this...')
cursor.execute("INSERT INTO {table_name} (description, url) VALUES (%s, %s);".format(table_name=table_name),
(table_name.encode("utf-8"),
key.encode("utf-8"),
data[key].encode("utf-8")))

How to write proper MySQL Insert statement in Python?

I am trying to insert two columns of data into a MySQL table from Python. And my Insert statement is true, I guess. But I am still getting 1064 error code.
This is for MySQL server version 8.0.12 and Python 3.7. I had tried changing different methods of inserting dynamic variables.
#alter is the data value read from serial port
sql="select * from stds"
cur.execute(sql)
records=cur.fetchall()
if cur.rowcount>0:
print('Number of rows - ',cur.rowcount)
else:
print('No data in table')
for row in records:
print(row)
if row[1]==alter:
print("Student exists : ",row[1])
date = datetime.datetime.now()
print(type(date))
ins = (alter, date)
sql = "Insert into 'attendance' ('stdid', 'dt') VALUES (%s,%s)"
cur.execute(sql, ins)
cnn.commit()
print('Sucessfully Stored the Record')
#success(alter)
break
else:
print("Student doesn't exist")
I am getting this error message
Error:
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''attendance' ('stdid', 'dt') VALUES ('FE0070E83D5B','2019-08-01 09:09:06.162304'' at line 1
And I am expecting that these read tag values are inserted successfully​.
Identifiers (e.g. column and table names) in MySQL (and most other flavors of SQL as well) do not take single quotes. They take either no quotes, double quotes, or maybe backticks in the case of MySQL. Try this version:
sql = "INSERT INTO attendance (stdid, dt) VALUES (%s, %s)"
ins = (alter, date)
cur.execute(sql, ins)
cnn.commit()

Can't get the right SQL syntax using pymsql, error 1064

My output works in csv, but not when trying to insert it into mysql. I get the following error and have not been able to figure it out. I'm a novice so I may be missing something obvious. Same error in Python 2x and 3x.
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key, title, content, start_date, end_date, initial_update) VALUES('reddit', 'h' at line 1")
mainDB_cnx = pymysql.connect(user='XXXX', password='XXXX',
host='XXXX',
database='Test', use_unicode=True, charset="utf8mb4")
with mainDB_cnx:
mainDB_cursor = mainDB_cnx.cursor()
mainDB_cursor.execute(
"INSERT INTO reddit(site, site_url, key, title, content, start_date, end_date, initial_update) VALUES(%s, %s, %s, %s, %s, STR_TO_DATE(%s,'%%Y-%%m-%%d'), STR_TO_DATE(%s,'%%Y-%%m-%%d'), STR_TO_DATE(%s,'%%Y-%%m-%%d'))",
(["reddit", "http://www.reddit.com", url, title, content, datetime.strptime(date,'%d %B %Y').strftime('%Y-%m-%d'), datetime.strptime('2018-07-25','%Y-%m-%d').strftime('%Y-%m-%d'), datetime.strptime('2018-07-25','%Y-%m-%d').strftime('%Y-%m-%d')]))
print("Successful")
KEY is a reserved word in the MySQL dialect of structured query language. See this. https://dev.mysql.com/doc/refman/8.0/en/keywords.html#keywords-8-0-detailed-K
So you must wrap that column name in delimiters whenever you mention it.
Try
INSERT INTO reddit (side, site_url, `key`, title, ....
Or, better, don't use reserved words for the names of columns in your tables. The next programmer to work on your system will thank you.

Python mysql timestamp insert does not work but will work in mysql client

When in the mysql client the following query works perfectly:
INSERT INTO VOLUMES (VOLUMEID, NAME, TYPE, SERVERID,SIZE, DEVICENAME, CREATIONDATE) VALUES ('vol-b67d73b7', 'TBC','gp2', 'i-7d445a89', '8', '/dev/sda1', '2014-11-24T07:40:37.921Z');
However when I use the same query in my python script I get the following error:
1265: Data truncated for column 'CREATIONDATE' at row 1
Here is the python code:
try:
db = mysql.connector.connect(**config)
cursor = db.cursor()
for volume in volumes:
ins_stmt = ("INSERT INTO VOLUMES (VOLUMEID, NAME, TYPE, SERVERID,"
"SIZE, DEVICENAME, CREATIONDATE) VALUES ('{0}', 'TBC',"
"'{1}', '{2}', '{3}', '{4}', '{5}');")
to_execute = ins_stmt.format( volume.id, volume.type,
volume.attach_data.instance_id, volume.size,
volume.attach_data.device, volume.create_time)
cursor.execute(to_execute)
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something is wrong with your user name or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("Database does not exists")
else:
print(err)
else:
db.close()
I don't understand what could be wrong. Can anyone help?
You need to use SQL parameters and have the database adapter handle quoting for you:
ins_stmt = ("INSERT INTO VOLUMES (VOLUMEID, NAME, TYPE, SERVERID,"
"SIZE, DEVICENAME, CREATIONDATE) VALUES (?, 'TBC',"
"%s, %s, %s, %s, %s);")
params = (volume.id, volume.type,
volume.attach_data.instance_id, volume.size,
volume.attach_data.device, volume.create_time)
cursor.execute(to_execute, params)
Not only does this ensure that you don't run into problems with pre-existing quoting characters in your strings, it also avoids SQL injection attacks (where a user crafts data that breaks out of the quoting and issues additional SQL statements you did not intent to allow). Don't let Little Bobby Tables get you!
Next, make sure your timestamps are in a format that MySQL supports; your timestamp appears to have a 3-digit fraction and a timezone specifier; MySQL 5.6.4 and up appears to expect a 6 digit fraction, a space instead of the T, and no timezones, so perhaps you should remove that portion from your volume.create_time string:
params = (volume.id, volume.type,
volume.attach_data.instance_id, volume.size,
volume.attach_data.device,
volume.create_time.replace('T', ' ').partition('.')[0])
The message you see is telling you that MySQL won't accept the date as formatted. Your MySQL client is either only issuing a warning (instead of an error), or it is configured to allow invalid dates (ALLOW_INVALID_DATES is set). If a warning was set you need to ask MySQL for the warning with show warnings in the client.

Can't insert tuple to mssql db

I am using pymssql in Python 3.3 to communicate with my Mssql db. And I am trying to save the data from a user in a tuple to the database, but I keep getting this weird error:
pymssql.ProgrammingError: (102, b"Incorrect syntax near '\\'.DB-Lib error message 102, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\n")
My method, the error is showing in the last line:
user.password = user.password.encode('utf_8')
user.password = encrypt_RSA(user.password)
cursor.execute('INSERT INTO Usertable VALUES(%i, \'%s\', \'%s\', \'%s\', \'%s\', \'%s\', \'%s\')' % user.get_usertuple())
I suspect it has something to do with the encoding and encrypting:
def encrypt_RSA(message, public_key_loc = "pubkey.pem"):
'''
param: public_key_loc Path to public key
param: message String to be encrypted
return encoded encrypted string
'''
key = open(public_key_loc, "r").read()
rsakey = RSA.importKey(key)
rsakey = PKCS1_OAEP.new(rsakey)
encrypted = rsakey.encrypt(message)
return encrypted
Can anyone tell what I am doing wrong here? And how to fix it?
EDIT:
My query now looks like this:
cursor.execute('INSERT INTO Usertable VALUES(%i, %s, %s, %s, %s, %s, %s)' % user.get_usertuple())
But that gives me another error: pymssql.OperationalError: (103, b"The identifier that starts with (LONG TEXT) is too long. Maximum length is 128.DB-Lib error message 103, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\nDB-Lib error message 102, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\n")
use bind variables. it is safer, it is kinder to the DB.
cursor.execute('SELECT * FROM persons WHERE salesrep=%s', 'John Doe')
your strings will be automatically and properly wrapped in quotes.

Categories