83

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.

4
  • Do 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 Commented Oct 29, 2016 at 1:33
  • Old thread but shouldn't the last % mark in your code be a , comma, otherwise it's just the same? @zelusp Commented Jul 15, 2019 at 6:08
  • Nope, I think that's right - unless you ran my code and I'm wrong. % (data, condition) is taking the variables data and condition and putting it into the two %s placeholders. Commented Jul 15, 2019 at 20:32
  • That's just python string formatting, which replaces. If condition were, for example, " or 1 == 1 or" , for example, you would have a problem. cur.execute provides escaping by doing cur.execute('SOME COMMAND ?', [value]). ? is replaced with value. Commented Jul 21, 2019 at 1:28

7 Answers 7

105
conn.escape_string()

See MySQL C API function mapping: http://mysql-python.sourceforge.net/MySQLdb.html

Sign up to request clarification or add additional context in comments.

7 Comments

+1 ... Perfect answer. Surprised to see so many complicated answers out there. Clearly, param'ed queries don't take into account for long strings (text) that is being stored.
+1 I love the black and white HTML pages with swear words and code.
_mysql.escape_string("input's " ) can also work to escape an ascii string for mysql. Apparently not for unicode though. _mysql.escape_string( u"input's éh " )
What are the parameters for this function?
doesnt work... converts string to byte format
|
86

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

Somewhat upsetting that it forces quotation marks. For example, if you were inserting into a conditional table (TABLE_A instead of 'TABLE_A'), you couldn't do it completely with this method.
bozdoz, this is very much by design as it prevents SQL Injection. If you want to insert into a conditional table, first make sure there is no way a user submitted string can be used for the table name, and then just add it directly to the query.
This is definitely the correct answer. Never know what new ways will exist to get around string escaping (Like we currently do over in the PHP world...). Just safer to do prepared statements always
The builder formats using exactly the same call to 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.
Storing Windows file paths as strings in a database column with the '\' separator is useful. Otherwise, when constructing SQL queries directly by interpolation or format strings, you may encounter code issues where you need to use "\\" or "\\\\" depending on the specific context.
22
>>> 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

Hm. Seems as if StackOverflows highlighting algorithm doesn't know Pythons triple quotes.
This is especially helpful for use in routines where the SQL string is constructed piecemeal.
MySQLdb fork for Python3: github.com/PyMySQL/mysqlclient-python
4

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

0

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

-3

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

Note that sqlescapy doesn't properly escape quotes or double quotes, it simply removes them: github.com/elouajib/sqlescapy/blob/master/sqlescapy/…
-5

{!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))

Python3 docs

1 Comment

Your Sample Program link is broken, and single quotes are ascii

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.