2010-08-23 5 views
5

Esta es mi consulta.¿Cuál es la mejor estrategia de carácter de escape para el combo Python/MySQL?

cursor2.execute("update myTable set `"+ str(row[1]) +"` = \"'" + str(row[3]) +"'\" where ID = '"+str(row[0])+"'") 

Está fallando cuando los valores de las filas tienen comillas dobles "algún valor". ¿Cómo escapo a todos los personajes especiales?

+2

La mejor estrategia de escape para Python + MySQL se preparan . – zneak

+0

¿Podrías por favor elaborar? ¡Gracias! – ThinkCode

+0

@zneak: prepare una inserción extendida con 1k filas. – Mchl

Respuesta

13

Aquí se muestra un ejemplo:

import MySQLdb 
column = str(MySQLdb.escape_string(row[1])) 
query = "update myTable set %(column)s = %%s where ID = %%s" % dict(column = column) 
cursor2.execute(query, [row[3], row[0]]) 

actualización

He aquí un breve comentario:

column = str(MySQLdb.escape_string(row[1])) 

siempre una buena idea para escapar de todo lo que entra en una consulta. En este caso, estamos agregando dinámicamente un nombre de columna y, por lo tanto, debe escaparse antes de que se ejecute la consulta.

query = "update myTable set %(column)s = %%s where ID = %%s" % dict(column = column) 

Formulo la consulta aquí. Estoy tratando de lograr dos cosas: (1) formar una consulta con el nombre de columna rellenada usando la variable column declarada en la línea anterior (2) agregar marcadores de posición que serán completados por parámetros reales durante la ejecución de la consulta.

El fragmento dict(column = column) es en realidad otra forma de crear el diccionario {'column': column}. Esto es posible usando el constructor dict. No quiero completar el resto de los titulares de lugar, así que los escapo usando dos signos de porcentaje (%%).

cursor2.execute(query, [row[3], row[0]]) 

Finalmente, ejecute la consulta. Si imprime una consulta antes de ejecutar, verá la cadena update myTable set column_name = %s where ID = %s.

+0

¿Podría explicarme su enfoque? ¡Funcionó brillantemente! No entendí la parte dict (columna = columna). – ThinkCode

+0

Respuesta actualizada. Véase más arriba. –

+1

El escape de columna es incorrecto aquí, las columnas son identificadores y necesitan 'caracteres alrededor y se doblaron' 'si hay algunas tesis adentro (en el nombre de columna), no es una cita que escapa. – regilero

7

Para los valores, debe usar consultas preparadas para incrustarlos. Para las filas, no estoy muy seguro ... depende de su configuración. Probablemente desees aceptar cualquier personaje que esté por encima del valor ASCII 32 excepto un backtick sin guardar. Sin embargo, no creo que haya una función específica para esto.

cursor2.execute("UPDATE myTable SET `" + str(row[1]) + "` = ? WHERE ID = ?", (row[3], row[1])) 

consultas preparadas tienen signos de interrogación donde debería haber variables y se pasa en una lista o una tupla como segundo argumento para especificar lo que deben ser sustituidos con. El conductor se encargará de hacer que los valores sean seguros. Sin embargo, solo puedes poner marcas de interrogación donde se esperan valores; por lo que no puede usarlos como nombres de columna.

7

Usted debe aprender a utilizar los parámetros de consulta:

colname = str(row[1]).replace("`", "\\`") 
sql = "update myTable set `%s` = :col1 WHERE ID = :id" % (colname) 
cursor2.execute(sql, {"col1":str(row[3]), "id":str(row[0])}) 
+0

_mysql_exceptions.ProgrammingError: (1064, "Tiene un error en su sintaxis de SQL, consulte el manual que corresponde a su versión de servidor MySQL para la sintaxis correcta para usar cerca de ': col1 WHERE ID =: id' en la línea 1") Cualquiera punteros? Gracias .. – ThinkCode

+0

Quizás los parámetros nombrados sean solo para Oracle. Intenta usar parámetros posicionales '?' En lugar de la respuesta de @zneak. –

2

Al usar Oracle MySql connector se puede escapar caracteres especiales de una manera siguiente:

consultas
import mysql.connector 
from mysql.connector import conversion 

query = "SELECT id, code, name, description FROM data WHERE code='{:s}'" 

escaped_text = conversion.MySQLConverter().escape(unescaped_text) 

cursor.execute(query.format(escaped_text)) 
+0

Esto aparentemente no funciona como se esperaba: 'conversion.MySQLConverter(). Escape ('blah; truncate other;')' => ''blah; truncar otro; ''. – b4hand

Cuestiones relacionadas