2012-07-06 15 views
7

¿Cómo puedo escapar de la entrada a una base de datos MySQL en Python3? estoy usando PyMySQL y funciona muy bien, pero cuando trato de hacer algo como:¿Cómo puedo escapar de la entrada a una base de datos MySQL en Python3?

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

no funcionará si la cadena tiene ' o ". También probé:

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

El problema con esto es que la biblioteca (PyMySQL) utiliza la sintaxis de formato para python2.X, %, que no funciona más. también encontré esta posible solución

conn.escape_string() 

en here, pero no sé dónde poner este código. Esto es todo lo que tengo:

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: lo solucionó! En PyMySQL la manera correcta es la siguiente:

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() 

Donde la línea text = conn.escape(request[1]) es lo que se escapa el código. Lo encontré dentro del código PyMySQL. Ahí, request[1] es la entrada.

+1

Genial. Sin embargo, debes publicar la segunda mitad de tu pregunta como respuesta. Puedes aceptar tu propia respuesta. – Grilse

+0

Vaya, no vi ese botón antes. – user1460016

+0

Si se resuelve, marque su propia pregunta como aceptada. :-) – Jocelyn

Respuesta

6

Resuelto. En PyMySQL la manera correcta es la siguiente:

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() 

Donde la línea text = conn.escape(request[1]) es lo que se escapa el código. Lo encontré dentro del código PyMySQL. Ahí, request[1] es la entrada.

14

Aunque la respuesta "resuelta" funciona, no es una buena práctica. Al usar una biblioteca que se ajuste a la DBI de Python, debe usar variables de vinculación en lugar de formatear una cadena y pasarla a ejecutar. Hay peligros inherentes a esa metodología.

Por lo tanto, esta es la forma correcta de hacerlo:

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

Tenga en cuenta que esto no es una cadena de formato, sino una variable de vinculación pasado al cursor de ejecución.

Para más detalles: Python DBI PEP

+0

Tenga en cuenta que se debe usar '% s' incluso con diferentes tipos, como enteros. Estaba tratando de usar '% d' y obtuve el error: 'formato% d: se requiere un número, no str'. – nephets

0

Listo para usar la función cooperadora

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() 

Ejemplo de uso

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

Referencia: 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. 
Cuestiones relacionadas