I'm trying to correctly escape urls to enter into a mysql connection, but apparently I'm doing it wrong:
>>> import MySQLdb
>>> db = MySQLdb.connect(host="localhost",user="...",passwd="...",db="...")
>>> cur = db.cursor()
>>> cmd = "insert into S3_data (url) VALUES ('http://google.com')"
>>> cur.execute(cmd)
1
>>> cur.execute(MySQLdb.escape_string(cmd))
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
cur.execute(MySQLdb.escape_string(cmd))
File "C:\Python34\lib\site-packages\MySQLdb\cursors.py", line 220, in execute
self.errorhandler(self, exc, value)
File "C:\Python34\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
raise errorvalue
File "C:\Python34\lib\site-packages\MySQLdb\cursors.py", line 209, in execute
r = self._query(query)
File "C:\Python34\lib\site-packages\MySQLdb\cursors.py", line 371, in _query
rowcount = self._do_query(q)
File "C:\Python34\lib\site-packages\MySQLdb\cursors.py", line 335, in _do_query
db.query(q)
File "C:\Python34\lib\site-packages\MySQLdb\connections.py", line 280, in query
_mysql.connection.query(self, query)
_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 near '\\'http://google.com\\')' at line 1")
As you can see the command works ok, but the escaping fails. What am I missing here?
Also, does escape string handle multi-byte encodings?
Thanks
I believe if you use parameters you shouldn't have a problem.
cmd = "INSERT INTO S3_data (url) VALUES (%s)"
args = 'http://google.com'
cur.execute(cmd, args)
Related
I am trying to update all rows of the specific column in MSSQL database using pymssql. But I encountered with this error:
" Traceback (most recent call last):
File "src\pymssql_pymssql.pyx", line 460, in pymssql._pymssql.Cursor.execute
File "src\pymssql_mssql.pyx", line 1104, in pymssql._mssql.MSSQLConnection.execute_query
File "src\pymssql_mssql.pyx", line 1135, in pymssql._mssql.MSSQLConnection.execute_query
File "src\pymssql_mssql.pyx", line 1268, in pymssql._mssql.MSSQLConnection.format_and_run_query
File "src\pymssql_mssql.pyx", line 1806, in pymssql._mssql.check_cancel_and_raise
File "src\pymssql_mssql.pyx", line 1852, in pymssql._mssql.raise_MSSQLDatabaseException
pymssql._mssql.MSSQLDatabaseException: (102, b"Incorrect syntax near ','.DB-Lib error message 20018, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\n") "
Here is my code:
params = [tuple(x) for x in all_list]
# print(params)
query = """UPDATE dbo.MYTABLE SET KeyWords=%s WHERE KeyWords=%s"""
for i in params:
val = ("NULL", i)
cursor.execute(query, val)
conn.commit()
print(cursor.rowcount)
Params variable is a list of tuples that are going to be the new values of my column. In the column, all values are filled with NULL and I want to update with the Params variable.
Any suggestion?
Thank you for help, in advance.
I'm trying to check if database exists in Python. I found that it can be done using the following sql statement: cur.execute(f'SHOW DATABASES LIKE {event["db_name"]}') However,after trying to execute it I get the following errors:
[ERROR] 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 'TestLAU' at line 1")
Traceback (most recent call last):
File "/var/task/handler.py", line 63, in handler
cur.execute(f'SHOW DATABASES LIKE {event["db_name"]}')
File "/var/task/pymysql/cursors.py", line 170, in execute
result = self._query(query)
File "/var/task/pymysql/cursors.py", line 328, in _query
conn.query(q)
File "/var/task/pymysql/connections.py", line 517, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/var/task/pymysql/connections.py", line 732, in _read_query_result
result.read()
File "/var/task/pymysql/connections.py", line 1075, in read
first_packet = self.connection._read_packet()
File "/var/task/pymysql/connections.py", line 684, in _read_packet
packet.check_error()
File "/var/task/pymysql/protocol.py", line 220, in check_error
err.raise_mysql_exception(self._data)
File "/var/task/pymysql/err.py", line 109, in raise_mysql_exception
raise errorclass(errno, errval)
You miss an apostrophe in your statement and you can use % in your LIKE statement in order to match more results, try the following:
cur.execute(f"SHOW DATABASES LIKE '%{event["db_name"]}%;'")
more about LIKE operator:
LIKE 'a%' Finds any values that start with "a"
LIKE '%a' Finds any values that end with "a"
LIKE '%or%' Finds any values that have "or" in any position
LIKE '_r%' Finds any values that have "r" in the second position
LIKE 'a__%' Finds any values that start with "a" and are at least 3 characters in length
LIKE 'a%o' Finds any values that start with "a" and ends with "o"
Turns out the error was caused by the fact that I needed to surround the database name with quotes so the following SQL statement worked: cur.execute(f'SHOW DATABASES LIKE "{event["db_name"]}"')
So, I want to input data in multiple times with auto increment as primary key and return the primary key as the input result. so there's my code:
connectDB.py
import pymysql
class auth:
db = pymysql.connect("localhost","root","","rfid")
cursor = db.cursor()
def inputData(nama):
sql = "INSERT INTO auth (nama) VALUES ('%s');" % (nama)
try:
auth.cursor.execute(sql)
auth.db.commit()
result = auth.cursor.lastrowid
auth.db.close()
return result
except:
err = "Error: unable to fetch data"
auth.db.rollback()
auth.db.close()
return err
test.py
import re
import PyMySQL
from connectDB import auth
while True:
inputs2 = input("masukan nama: ")
hasil = auth.inputData(inputs2)
print(hasil)
so, when I do an input in the first time is success but when Itry to input again I got an error exception:
Traceback (most recent call last):
File "/home/pi/Desktop/learn/RFIDdatabase/connectDB.py", line 29, in inputData
auth.cursor.execute(sql)
File "/usr/local/lib/python3.4/dist-packages/pymysql/cursors.py", line 166, in execute
result = self._query(query)
File "/usr/local/lib/python3.4/dist-packages/pymysql/cursors.py", line 322, in _query
conn.query(q)
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 855, in query
self._execute_command(COMMAND.COM_QUERY, sql)
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 1071, in _execute_command
raise err.InterfaceError("(0, '')")
pymysql.err.InterfaceError: (0, '')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 12, in <module>
hasil = auth.inputData(inputs2)
File "/home/pi/Desktop/learn/RFIDdatabase/connectDB.py", line 41, in inputData
auth.db.rollback()
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 792, in rollback
self._execute_command(COMMAND.COM_QUERY, "ROLLBACK")
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 1071, in _execute_command
raise err.InterfaceError("(0, '')")
pymysql.err.InterfaceError: (0, '')
so, What the exception cause?
Of course you would get an exception - cause you close the connection after executing a query:
auth.cursor.execute(sql)
auth.db.commit()
result = auth.cursor.lastrowid
auth.db.close() # < HERE
return result
You probably getting an "operation on a closed cursor" exception which is handled by your overly broad bare except clause (which is bad) - then - the roll back is initiated at auth.db.rollback() which fails with a not descriptive and understandable error.
Other issues:
I would make the db and cursor instance variables instead of class variables (differences)
don't "string format" your queries - proper parameterize them
I'm trying to build a custom query and would like to apply .extra() after filter(). The statement looks like:
V.objects.filter(v_id__product__icontains=name)
Now it produces the valid SQL, which, however, does not have quotes around name:
WHERE `v_id`.`product` LIKE %xxx%
But when I add .extra() statement:
V.objects.filter(id__product__icontains=name).extra(where=[concat_str],params=[version,'%','%'])
, the query becomes invalid because there is no quotes aroung %xxx%:
WHERE `v_id`.`product` LIKE %xxx% AND 'yyy' LIKE CONCAT('%',version,'%')
All I need here is to add single quotes around %xxx%, to make it valid:
WHERE `vulnerabilities_cpeid`.`product` LIKE '%xxx%' AND 'yyy' LIKE CONCAT('%',version,'%')
However, I just do not know how to force Django to put %xxx% into single quotes when using icontains. Any help appreciated. Thank you in advance.
Full traceback:
INFO 2014-07-21 11:33:55,515 views: SELECT `vulnerabilities_vulnerability`.`identifier` FROM `vulnerabilities_vulnerability` INNER JOIN `vulnerabilities_vulnerability_cpe_id` ON (`vulnerabilities_vulnerability`.`id` = `vulnerabilities_vulnerability_cpe_id`.`vulnerability_id`) INNER JOIN `vulnerabilities_cpeid` ON (`vulnerabilities_vulnerability_cpe_id`.`cpeid_id` = `vulnerabilities_cpeid`.`id`) WHERE (`vulnerabilities_cpeid`.`product` LIKE %accountsservice% AND '0.6.15-2ubuntu9.7' LIKE CONCAT('%',version,'%'))
ERROR 2014-07-21 11:33:55,517 django.request: Internal Server Error: /vulndb/inventory/
Traceback (most recent call last):
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/home/sapegin/vulndb_mercurial/vulndb/vulndb/vulnerabilities/views.py", line 1650, in inventory
if ((vulnerabilities is not None) and (vulnerabilities.count() > 0)):
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/db/models/query.py", line 351, in count
return self.query.get_count(using=self.db)
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/db/models/sql/query.py", line 418, in get_count
number = obj.get_aggregation(using=using)[None]
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/db/models/sql/query.py", line 384, in get_aggregation
result = query.get_compiler(using).execute_sql(SINGLE)
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 818, in execute_sql
cursor.execute(sql, params)
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/db/backends/util.py", line 40, in execute
return self.cursor.execute(sql, params)
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/django/db/backends/mysql/base.py", line 119, in execute
return self.cursor.execute(query, args)
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/MySQL_python-1.2.4-py2.6-linux-x86_64.egg/MySQLdb/cursors.py", line 201, in execute
self.errorhandler(self, exc, value)
File "/home/sapegin/vulndb_mercurial/vulndb/HANA/PYTHON/Python/lib/python2.6/site-packages/MySQL_python-1.2.4-py2.6-linux-x86_64.egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
DatabaseError: (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 '0.6.15-2ubuntu9.7'' LIKE CONCAT(''%'',version,''%''))' at line 1")
ERROR 2014-07-21 11:33:55,517 django.request: Internal Server Error: /vulndb/inventory/
I bet the error is that you have extra quotes in your .extra call's parameters. Remove the quotes around %s and see if that fixes the problem.
In Django the DatabaseWrapper will automatically add quotes there. The 'icontains' operator is translated to 'icontains': 'LIKE %s', where %s will be replaced with the string which is concatenated with % signs before and after the search term.
Internally Django will use the quote_name function to do the quotation marks.
def quote_name(self, name):
if name.startswith("`") and name.endswith("`"):
return name # Quoting once is enough.
return "`%s`" % name
Maybe for your use-case the raw Query might be a better Solution:
Model.objects.raw('Select .... FROM .... WHERE ....', params=None, translations=None)
Have a look at: https://docs.djangoproject.com/en/dev/topics/db/sql/
I think alecxe is right the debug in .query is not sufficient.
I have a bug that I don't know how to fix or even reproduce:
query = "SELECT id, name FROM names ORDER BY id"
results = database.execute(query)
where the class Database contains:
def execute(self, query):
cursor = self.db.cursor()
try:
cursor.execute(query)
return cursor.fetchall()
except:
import traceback
traceback.print_exc(file=debugFile)
return []
This is how I open the database connection:
self.db = MySQLdb.connect(
host=mysqlHost,
user=mysqlUser,
passwd=mysqlPasswd,
db=mysqlDB
)
This is the stacktrace of the error:
File "foo.py", line 169, in application results = config.db.execute(query)
File "Database.py", line 52, in execute
return cursor.fetchall()
File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 340, in fetchall
self._check_executed()
File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 70, in _check_executed
self.errorhandler(self, ProgrammingError, "execute() first")
File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
ProgrammingError: execute() first
Do you have any ideas of why this is happening and how can I fix it? I searched on the internet and I found out that the reason may be having 2 cursors, but I have only one.
try this in your traceback it's for debugging:
except ProgrammingError as ex:
if cursor:
print "\n".join(cursor.messages)
# You can show only the last error like this.
# print cursor.messages[-1]
else:
print "\n".join(self.db.messages)
# Same here you can also do.
# print self.db.messages[-1]