python mysqldb how to correctly escape urls - python

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

updating columns in sql DB using pymssql

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.

How to Check if database exists in PyMySQL

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"]}"')

got exception when do a loop input to database Python

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

Django filter(icontains).extra produces wrong SQL syntax (no quotes)

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.

Python, MySQL and a weird error

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]

Categories

Resources