Python - MySQL syntax error - python

I tried to make a python command to update mysql on key duplicate
sql.run("INSERT INTO snapshots (id,username,data) VALUES ('%s','%s','%s') ON DUPLICATE KEY UPDATE data = VALUES(%s)" % (id,user.name,json.dumps(data),json.dumps(data)))
It works on data insert but on key duplicate, it throws this error
/usr/local/lib/python2.7/dist-packages/memsql/common/database.py at 166 > (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 \'{"achievements": {"150": 1448983913.491705, "200": 1448984742.809708, "204": 144\' at line 1')
I have tried KEY UPDATE data = '%s', KEY UPDATE data = VALUES(%s) and KEY UPDATE data = VALUES('%s') but none of them works.
What exactly did I do wrong here?

The root cause of the error is json-dumped string with not escaped " characters, caused by direct substituting the data into the query.
As #mgilson said, use cursor.execute() method and database driver will take care of escaping.

Related

MYSQL parameter python issue with table name

I am new in using python API to send a query to mysql.
My issue is very easy to reproduce. I have a table named "ingredient" and I would like to select the rows from python using parameters
If I do cursor.execute("select * from ?",('ingredient',)) I get the error message : Error while connecting to MySQL Not all parameters were used in the SQL statement MySQL connection is closed
I I do cursor.execute("select * from ?",'ingredient') I get the error message : Error while connecting to MySQL 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 '?' at line 1
Same issues using %s instead of ?. Using the other type of single quote on 'ingredient' instead of 'ingredient' does not give results either.
How is this supposed to work here ?
You just can't pass a table name as parameter to a query. The parameterization mechanism is there to pass literal values, not object names. Keep in mind that the database must be able to prepare the query plan from just the parameterized string (without the actual parameter value), which disqualifies using metadata as parameter.
You need string concatenation instead:
cursor.execute("select * from " + yourvar);
Note that, if the variable comes from outside your program, using such contruct exposes your code to SQL injection. You need to manually validate the value of the parameter before execting the query (for example by checking it against a fixed list of allowed values, or by querying the information schema of the database to ensure that the table does exist).
Does your query work if you just write:
cursor.execute("SELECT * FROM ingredient")
?

pymysql.err.ProgrammingError 1064 in simple multiline SQL query for mariadb

I have tried everything and keep getting this error:
pymysql.err.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
'INSERT INTO tabSingles (doctype, field, value) VALUES ('Bank Reconciliation', 'a' at line 2")
Expanded query (after python format expansion):
SELECT value INTO #var FROM tabSingles WHERE doctype = 'Bank Reconciliation' AND field = 'bank_account';
INSERT INTO tabSingles (doctype, field, value) VALUES ('Bank Reconciliation', 'account', #var);
DELETE FROM tabSingles WHERE doctype = 'Bank Reconciliation' AND field = 'bank_account';
Can anyone see the problem? Is there some issue with multi-line queries? I have tried the individual lines on the mariadb command line and they appear to work as expected. I've also tried both frappe.db.sql and multisql (thought it meant multiline sql but doesn't). If I comment line 2 out, it also errors on line 3. Sorry to disturb but I've been staring at this for hours and cannot figure it out!
EDIT:
The obvious answer is this, but I'd still like to know why it doesn't like the original query:
UPDATE tabSingles SET field='{new_name}' WHERE doctype='{doctype}' AND field='{old_name}';
For security reasons (mainly SQL injection) MariaDB (and MySQL) servers don't support the execution of multiple SQL statements by default.
For supporting multiple statements execution the client needs to send COM_SET_OPTION command and MYSQL_OPTION_MULTI_STATEMENTS_ON flag to the server, which is not supported by PyMySQL.
Do not try to run more than one statement in a call.
Do use BEGIN and COMMIT.
Do use FOR UPDATE.
You need 5 separate commands:
BEGIN;
SELECT ... FOR UPDATE; -- to keep other connections from messing with the row(s).
UPDATE ...;
DELETE ...
COMMIT; -- do all of the above "atomically"

Inserting error in mysql query using python

I am trying to insert values into a row of mysql database in a way that not be vulnerable to injection, but gives my syntax error. This is a piece of my code which causes the error:
cursor.execute("INSERT INTO api.mytable(id) VALUES (:id);", {"id": 1})
and error:
ERROR in connection: (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 ':id)' at line 1")
code you please tell me what's the wrong with my code?
I am assuming id is given as some kind if input! Hence you can always check for the required format and allow only required ones! This is to avoid SQL injection!. Hence the natural formatting as shown below should do the job! And this is very basic level checking!
id_in = input("Here is the id taken " ) ## can be through any source . It is just an example
if isinstance(id_in,int): ##Please mention the required format here I am assuming it as integer
cursor.execute("INSERT INTO api.mytable(id) VALUES (%s);", (id_in))
else:
##do some stuff here

Insert to MySQL fails with error

I'm using a Python script that I have been using many times before to load CSV data into MySQL tables.
I modified the script for a very simple insert but it fails and I can't see why.
I've gone through the MySQL documentation of the Python connector, compared my syntax and I went through all the related articles on Stackoverflow but I can't find the reason. I've also checked the quotes I'm using as that is a common error.
Perhaps someone can help:
if row[0]:
s=row[0]
d=s[s.rfind('/')+1:len(s)-4]
cursor.execute("INSERT INTO `tab` (`did`) VALUES (%s)",(d))
I've checked print(d) and d is populated correctly.
The error I'm getting is
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 '%s)' at line 1
If anyone can spot the (probably very silly) error, please help. Thanks.
The problem is that in
cursor.execute("INSERT INTO `tab` (`did`) VALUES (%s)",(d))
the (d) passed as params is a string with parentheses around it, not a tuple.
Here's how a mysql-connector cursor checks its params:
if params is not None:
if isinstance(params, dict):
for key, value in self._process_params_dict(params).items():
stmt = stmt.replace(key, value)
elif isinstance(params, (list, tuple)):
psub = _ParamSubstitutor(self._process_params(params))
stmt = RE_PY_PARAM.sub(psub, stmt)
if psub.remaining != 0:
raise errors.ProgrammingError(
"Not all parameters were used in the SQL statement")
So in your case though params is not None, it is not something accepted as params either and parameter substitution does not take place.
The fix then is simply to pass a tuple to cursor.execute() (a list works too):
cursor.execute("INSERT INTO `tab` (`did`) VALUES (%s)", (d,))
I think your string formating is wrong. It should probably be:
cursor.execute("INSERT INTO `tab` (`did`) VALUES (?)",d)
But you should check in the docs for your database library. I'm pretty sure the problem is with the placeholder in the query.

Correct SQL usage in Python Using PYMYSQL

I am attempting to write a SQL in python using PYMYSQL, which searches a table for a certain record with a set value, however while this sounds simple I cannot seem to do it below is my query:
SELECT Series_ID FROM series_information WHERE Series_Name "'+data +'"'
where the data is the value that I am searching for however the following error occurs:
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 \'"Spice And Wolf"\' at line 1')
The problem I believe is that I am not sure how to properly escape the data value if it has spaces in it and therefore would require quotation marks in the SQL query.
You're missing a comparison (like, =, etc) between Series_Name and data, as well as a ';' on the end of the query.
`'SELECT Series_ID FROM series_information WHERE Series_Name = "'+data +'";'
`SELECT Series_ID FROM series_information WHERE Series_Name "'+data +'"'`
Is not a valid SQL query did you mean:
`'SELECT Series_ID FROM series_information WHERE Series_Name like "'+data +'"'`

Categories