How to debug 'You have an error in your SQL syntax' - python

There are several questions on You have an error in your SQL syntax - but they all seem to address a specific syntax error in the query, which is generally not helpful to others.
My question is how can I get the formatted query from a MySQL command in Python so that I can actually inspect it?
So I have a statement like:
cursor.execute("INSERT INTO products(acc, title, sku, price, price_checked, desc, imgs) VALUES (%s,%s,%s,%s,%s,%s,%s)", (1, prod.title, prod.sku, prod.price, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), prod.desc, prod.imgs))
And the error is:
_mysql_exceptions.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 n
ear 'desc, imgs) VALUES (1,'Holy Stone HS700 FPV Drone with 1080p HD Camera Live Vide' at line 1")
Any idea how I can get the executed query? I don't want to format the query myself then print it before executing, but rather use MySQL's built in formatting for security reasons, mainly.

DESC is a keyword in SQL for sorting in descending order. You can't call one of your parameters "desc" because it will be interpreted as such. Think about if you called one of your columns "Select"; it's the same issue. You need to rename that field.
Initially I was focused on prod.desc but in your query string, you have 'desc' listed as an actual column name: "... products(acc, title, sku, price, price_checked, desc, imgs)"
You can see the last query run using the advice here but I can't test as I don't have any MySQL instance.

Related

Parameterize an MySQL IN clause in Python code

I was looking at this similar question: Parameterize an SQL IN clause
But the solution is not using Python, so I had to raise a new question:
How do I parameterize a query containing an IN clause, the strings 'ruby','rails','scruffy','rubyonrails' comes from a column of a dataframe
SELECT * FROM Tags
WHERE Name IN ('ruby','rails','scruffy','rubyonrails')
ORDER BY Count DESC
The dataframe df might look like:
column1 column2...
ruby .
rails .
scruffy .
xxx
xxxx
Here's what I've tried:
I converted the first column to a list and name it list, then update the second line in the query:
WHERE Name IN %(list)s
But this gave me an error: sqlalchemy.exc.ProgrammingError: (MySQLdb._exceptions.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 'where Name IN (('ruby','rails','xxx','xxxx','xxx','' at line 2")
I also tried list = str(list)[1:-1] to remove the square bracket, but then I got error: MySQLdb._exceptions.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 'where Name IN ('\\'ruby\\', \\'rails\\', \\'xxxxx\\', \\'xxx\\',' at line 2")
My question is what format/datatype I should use for df[column1] to get this working? Can someone help please? Thanks.
The only answer here doesn't work, since I've resolved this, so here's the solution: turns out I only need to convert it to a list (with the square bracket), no need to remove the bracket otherwise it won't work!
Maybe you can convert the column list to a tuple:
col_tuple = tuple(list)
Then use a python f-string in your query:
f"""SELECT * FROM Tags
WHERE Name IN {col_tuple}
ORDER BY Count DESC"""

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

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