Question

How can I escape the input to a MySQL db in Python3? I'm using PyMySQL and works fine, but when I try to do something like:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  '{}'".format(request[1]))

it won't work if the string has ' or ". I also tried:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  %s",request[1])

The problem with this is that the library (PyMySQL) uses the formatting syntax for Python2.x, %, that doesn't work anymore. I also found this possible solution

conn.escape_string()

in here, but I don't know where to add this code. This is all I got:

import pymysql
import sys
conn = pymysql.connect( host   = "localhost",
            user   = "test",
            passwd = "",
            db     = "test")
cursor = conn.cursor()
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  {}".format(request[1]))

result = cursor.fetchall()

cursor.close()
conn.close()

Edit: I solved it! In PyMySQL the right way is like this:

import pymysql
import sys
conn = pymysql.connect(host="localhost",
            user="test",
            passwd="",
            db="test")
cursor = conn.cursor()
text = conn.escape(request[1])
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  {}".format(text))

cursor.close()
conn.close()

Where the text = conn.escape(request[1]) line is what escapes the code. Found it inside PyMySQL code. There, request[1] is the input.

Était-ce utile?

La solution 2

Solved. In PyMySQL the right way is like this:

import pymysql
import sys
conn = pymysql.connect(host="localhost",
            user="test",
            passwd="",
            db="test")
cursor = conn.cursor()
text = conn.escape(request[1])
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` =  {}".format(text))

cursor.close()
conn.close()

Where the text = conn.escape(request[1]) line is what escapes the code. Found it inside PyMySQL code. There, request[1] is the input.

Autres conseils

Although the "solved" answer works, it is not best practice. When using a library conforming to the Python DBI, you should be using bind variables rather than formatting a string and passing it to execute. There are dangers inherent in that methodology.

Therefore, this is the right way to do it:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = %s", text)

Note that this is not a format string but a bind variable passed to the executing cursor.

For details: Python DBI PEP

Ready to use helper function

def mysql_insert(conn, table, row):
    cols = ', '.join('`{}`'.format(col) for col in row.keys())
    vals = ', '.join('%({})s'.format(col) for col in row.keys())
    sql = 'INSERT INTO `{0}` ({1}) VALUES ({2})'.format(table, cols, vals)
    conn.cursor().execute(sql, row)
    conn.commit()

Usage example

insert_into(conn, 'people', {
    'firstname': 'John',
    'lastname': 'Doe',
    'age': 18, })

Reference: https://github.com/PyMySQL/PyMySQL/blob/master/pymysql/cursors.py#L157-L158

def execute(self, query, args=None):

If args is a list or tuple, %s can be used as a placeholder in the query.
If args is a dict, %(name)s can be used as a placeholder in the query.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top