I use Python and MySQLdb to download web pages and store them into database. The problem I have is that I can't save complicated strings in the database because they are not properly escaped.
Is there a function in Python that I can use to escape a string for MySQL? I tried with ''' (triple simple quotes) and """, but it didn't work. I know that PHP has mysql_escape_string(), is something similar in Python?
Thanks.
7 Answers 7
conn.escape_string()
See MySQL C API function mapping: http://mysql-python.sourceforge.net/MySQLdb.html
7 Comments
The MySQLdb library will actually do this for you, if you use their implementations to build an SQL query string instead of trying to build your own.
Don't do:
sql = "INSERT INTO TABLE_A (COL_A,COL_B) VALUES (%s, %s)" % (val1, val2)
cursor.execute(sql)
Do:
sql = "INSERT INTO TABLE_A (COL_A,COL_B) VALUES (%s, %s)"
cursor.execute(sql, (val1, val2))
5 Comments
db.literal as escape does, so calling it "safer" is a bit of a misnomer. Use it because its easier for small queries, but don't be troubled that you're missing something when you have to craft a large query or script by hand.>>> import MySQLdb
>>> example = r"""I don't like "special" chars ̄\_(ツ)_/ ̄"""
>>> example
'I don\'t like "special" chars \xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf'
>>> MySQLdb.escape_string(example)
'I don\\\'t like \\"special\\" chars \xc2\xaf\\\\_(\xe3\x83\x84)_/\xc2\xaf'
3 Comments
Use sqlalchemy's text function to remove the interpretation of special characters:
Note the use of the function text("your_insert_statement") below. What it does is communicate to sqlalchemy that all of the questionmarks and percent signs in the passed in string should be considered as literals.
import sqlalchemy
from sqlalchemy import text
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import re
engine = sqlalchemy.create_engine("mysql+mysqlconnector://%s:%s@%s/%s"
% ("your_username", "your_password", "your_hostname_mysql_server:3306",
"your_database"),
pool_size=3, pool_recycle=3600)
conn = engine.connect()
myfile = open('access2.log', 'r')
lines = myfile.readlines()
penguins = []
for line in lines:
elements = re.split('\s+', line)
print "item: " + elements[0]
linedate = datetime.fromtimestamp(float(elements[0]))
mydate = linedate.strftime("%Y-%m-%d %H:%M:%S.%f")
penguins.append(text(
"insert into your_table (foobar) values('%%%????')"))
for penguin in penguins:
print penguin
conn.execute(penguin)
conn.close()
Comments
One other way to work around this is using something like this when using mysqlclient in python.
suppose the data you want to enter is like this <ol><li><strong style="background-color: rgb(255, 255, 0);">Saurav\'s List</strong></li></ol>. It contains both double qoute and single quote.
You can use the following method to escape the quotes:
statement = """ Update chats set html='{}' """.format(html_string.replace("'","\\\'"))
Note: three \ characters are needed to escape the single quote which is there in unformatted python string.
Comments
install sqlescapy package:
pip install sqlescapy
then you can escape variables in you raw query
from sqlescapy import sqlescape
query = """
SELECT * FROM "bar_table" WHERE id='%s'
""" % sqlescape(user_input)
1 Comment
{!a} applies ascii() and hence escapes non-ASCII characters like quotes and even emoticons.
Here is an example
cursor.execute("UPDATE skcript set author='{!a}',Count='{:d}' where url='{!s}'".format(authors),leng,url))
db_cur.execute('''UPDATE test_table SET field_1="%s" WHERE field_2="%s"''' % (data, condition))Note the triple single quotes and double quotes around%s%mark in your code be a,comma, otherwise it's just the same? @zelusp% (data, condition)is taking the variablesdataandconditionand putting it into the two%splaceholders.conditionwere, for example," or 1 == 1 or", for example, you would have a problem.cur.executeprovides escaping by doingcur.execute('SOME COMMAND ?', [value]).?is replaced with value.