Trying to sanitize very basic MySQL SELECT in Python/Django - python

This is driving my nuts. I have this very basic query that works without the sanitization statement but breaks with it. Everything I've read says to do it this way.
query = "SELECT COL1 FROM A_TABLE %s"
queryUserInput = "WHERE COL1 = 'user input value'"
cursor.execute(query, (queryUserInput,))
I receive the error:
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 '' WHERE ...
Top of the stack:
C:..\env\lib\site-packages\mysql\connector\connection_cext.py in
cmd_query
raw_as_string=raw_as_string)
Python 3.7
Django 2.1.3
Any advice is very appreciated.

Parameterisation is supposed to used to santitise a variable value which is being used to form part of the finished SQL - e.g. the 7 in a query such as SELECT * FROM user WHERE ID = 7. You can't parameterise a whole section of SQL the way you're doing - and indeed there should be no need to do so.
I don't know Python specifically, but logically I think your code should be:
query = "SELECT COL1 FROM A_TABLE WHERE COL1 = %s"
queryUserInput = "user input value"
cursor.execute(query, (queryUserInput,))
in order that it only parameterises the actual user input, and not any of the SQL.
(Your original code would produce a SQL string something like SELECT COL1 FROM A_TABLE 'WHERE COL1 = \'user input value\'' which clearly is not valid SQL at all, due to everything after A_TABLE being contained within a string literal.)
This documentation (of the execute() method) shows you some other examples of correct usage: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

you can try it:
queryUserInput = "user input value"
cursor.execute("SELECT COL1 FROM A_TABLE WHERE COL1 = %s", [queryUserInput])
and django doc:
Executing custom SQL directly

Related

Passing Safe Query Parameters with SQLite in Python

I am working on a project that uses a HTML text input to retrieve data from a SQLite database.
The idea goes like this : the user types string representing a product number and I look into my database for that string.
I have tried to make my query safe for SQL injection as suggested in this tutorial because the data does not come from me.
cursor.execute("SELECT product_number FROM price_history WHERE product_number = %s';", (user_input, ))
However, when I try to execute my code, I get :
sqlite3.OperationalError: near "%": syntax error
There's an extra ' after %s.
Read the first paragraphs of the python docs on sqlite3 that show the correct way to use placeholders.
cursor.execute("SELECT product_number FROM price_history WHERE product_number = (?)", (user_input, )) should work.

Python SQL Statements with Greek Letters and UTF-8

Version:
Postgresql = 11.3
Python = 3.7.3
I have a python script that is collecting data from the web and storing it in a database for further analysis.
The below sql statement always returns false when it attempts to compare the variable that has been fetched from the web against what already exists in the database. I think this happens because of a mismatch in the encoding of the variable.
As an example, the variable = Σ1, and Σ1 already exists in the database, so the below sql statement should return TRUE but instead returns FALSE.
cur.execute("SELECT EXISTS(SELECT 1 FROM table_name WHERE column_name = %s)", (variable,))
When I run "cur.query" it shows the following query is being executed:
b"SELECT EXISTS(SELECT 1 FROM table_name WHERE column_name = '\xce\xa31')"
In pgadmin4, the variable is correctly stored as Σ1. If I run the sql query above directly in pgadmin4 with "Σ1" it returns true as expected.
But when I query to check if that variable already exists in the database from the python script, it returns false because it's comparing "Σ1" in the database against "\xce\xa31" in the sql query.
When I run "show CLIENT_ENCODING;" in pgadmin4 it shows "UTF8" and when I print "print(conn.encoding)" immediately before the sql statement in my script it also shows "UTF8".
Where am I going wrong?
If I do this:
>>> b"SELECT EXISTS(SELECT 1 FROM table_name WHERE column_name = '\xce\xa31')".decode("utf-8")
"SELECT EXISTS(SELECT 1 FROM table_name WHERE column_name = 'Σ1')"
it shows that you're not doing anything wrong. The query that you are seeing displayed back is shown as UTF-8 bytes but it is exactly the same as the Unicode query you want. I suspect that the Greek symbol in the database isn't exactly what your select expects to find. That may be because there are in fact several Unicode sigma signs: U+03A3, U+2211 and a few others besides.

How to check if a table exists using python?

I want to check whether the table exists or not before inserting the data.
This is what i have tried:
def checkTables(tablename):
stmt = "SHOW TABLES LIKE %s"%tablename
cursor.execute(stmt)
result = cursor.fetchone()
return result
But it gives me error saying:
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 'ctg_payload3' at line 1
Maybe it is not the best way.
As for my opinion, I will show tables;, then search the result.
And, I you cannot execute show tables like tablename;, no syntax like that.
edit 1
If you must do it in sql, use
show table status like 'table_name';
' is needed for this sql.
Try this query string :SHOW TABLES WHERE Tables_in_mydb LIKE '%tablename%' or
this one
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'my_database_name'
AND table_name LIKE '%tablename%'
Good luck
Try this.
def checkTables(tablename):
stmt = "SHOW TABLES LIKE '%s' "% ('%'+str(tablename)+'%')
cursor.execute(stmt)
result = cursor.fetchone()
return result

Python MySQL connector select with variable

I've this little query :
id = 'TESTID'
sql = "SELECT ID,PASSWORD FROM USERS WHERE ID = %s"
cursor.execute(sql,(id))
and i'm having the 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 'TESTID''' at line 1
I know this is something about double quotes. I've multiple other query that runs perfectly, but they have like 3 parameters
example :
id = 'TESTID'
GR = 'TEST'
name = 'HELLO'
last_name = 'WORLD'
sql = "INSERT INTO USERS (ID,GR,name,last_name) VALUES (%s,%s,%s,%s)"
cursor.execute(sql,(id,gr,name,last_name))
This one don't have 3 double quote at the beginning and 3 others at the end and runs perfectly so i dont know what to do now.
Thanks you.
One thing you should remember in python is that (7) is the same as 7. For a tuple of length 1, you have to say (7,) (note that important trailing comma).
So change this line:
cursor.execute(sql,(id)) to cursor.execute(sql,(id,)).

String replacement in SQL Query using Python

I have two queries in SQL which are the following:
q1 = select date_hour from table
And, the second query is:
q2 = select date(date_hour) from table
The only difference between these queries is the string date_hour and date(date_hour). SO, I tried parameterising my query in the following manner:
q1 = select %s from table
cur.execute(q1,'date')
cur.execute(q1,'date(date_hour)')
However, this throws an error which is:
not all arguments converted during string formatting
Why am I getting this error? How can I fix it?
Change the comma in cur.execute to %
Change this:
q1 = "select %s from table"
cur.execute(q1,'date')
cur.execute(q1,'date(date_hour)')
to:
q1 = "select %s from table"
cur.execute(q1 % 'date')
cur.execute(q1 % 'date(date_hour)')
It's unclear wich sql library you're using but assuming it uses the Python DB API:
Sql parameters are typically used for values, not columns names (while this is possible using stored procedures).
It seems you're confused between string formatting in python and sql parametized queries.
While %s can be used to format a string (see formatting strings) this is not the way to set sql parameters.
See this response to use sql parameters in python.
By the way i can't see anything wrong with this simple code:
cursor=cnx.curor()
query="select date_hour from table"
cursor.execute(query)
query="select date(date_hour) from table"
cursor.execute(query)
Change your code to something like this:
q1 = "select %s from table"
cur.execute(q1,['date'])
cur.execute(q1,['date(date_hour)'])
Check this

Categories