2010-09-01 22 views
52

Uso Python y MySQLdb para descargar páginas web y almacenarlas en la base de datos. El problema que tengo es que no puedo guardar cadenas complicadas en la base de datos porque no están escapadas correctamente.Escape cadena Python para MySQL

¿Existe alguna función en Python que pueda usar para escapar de una cadena para MySQL? Intenté con ''' (comillas simples triples) y """, pero no funcionó. Sé que PHP tiene mysql_escape_string(), ¿hay algo similar en Python?

Gracias.

+0

Do 'db_cur.execute ('' 'SET UPDATE test_table field_1 = "% s" DONDE field_2 ="% s "'' '% (datos, condición))' Tenga en cuenta las comillas simples triples y las comillas dobles alrededor de '% s' – zelusp

Respuesta

75
conn.escape_string() 

Ver MySQL C API de correlación de funciones: la función de texto http://mysql-python.sourceforge.net/MySQLdb.html

+1

+1 ... Respuesta perfecta. Sorprendido de ver tantas respuestas complicadas por ahí. Claramente, las consultas paramizadas no tienen en cuenta las cadenas largas (texto) que se almacenan. – Mike

+0

+1 Me encantan las páginas HTML en blanco y negro con malas palabras y código. – Droogans

+2

_mysql.escape_string ("input's") también puede funcionar para escapar de una cadena ascii para mysql. Aparentemente no es para Unicode. _mysql.escape_string (u "input's éh") –

1

Uso de sqlalchemy para eliminar la interpretación de caracteres especiales:

Nota el uso de la función text("your_insert_statement") a continuación. Lo que hace es comunicarle a sqlalchemy que todos los signos de interrogación y signos de porcentaje en la cadena pasada deben considerarse como literales.

import sqlalchemy 
from sqlalchemy import text 
from sqlalchemy.orm import sessionmaker 
from datetime import datetime 
import re 

engine = sqlalchemy.create_engine("mysql+mysqlconnector://%s:%[email protected]%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() 
+0

¿Quiere decir función? – User

+0

Sí, corregido. –

+0

¿Esto funciona para escapar de comillas simples? – user2654569

44

La biblioteca MySQLdb realidad lo hará por usted, si utiliza sus implementaciones para construir una cadena de consulta SQL en lugar de tratar de construir el suyo propio.

No hagas:

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)) 
+3

Un poco molesto que obliga a las comillas. Por ejemplo, si estuviera insertando en una tabla condicional (TABLE_A en lugar de 'TABLE_A'), no podría hacerlo completamente con este método. – bozdoz

+2

bozdoz, esto es mucho por diseño, ya que previene la inyección de SQL. Si desea insertar en una tabla condicional, primero asegúrese de que no haya forma de que una cadena enviada por el usuario pueda usarse para el nombre de la tabla, y luego simplemente agréguela directamente a la consulta. – techdude

+1

Esta es definitivamente la respuesta correcta. Nunca se sabe qué nuevas formas existirán para evitar el escape de cadenas (Como hacemos actualmente en el mundo PHP ...). Simplemente más seguro hacer declaraciones preparadas siempre –

3
>>> 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' 
+0

Hm. Parece que si el algoritmo de resaltado StackOverflows no conoce las comillas triples de pitones. –

Cuestiones relacionadas