Python MySQL escapar de caracteres especiales

Estoy usando python para insertar una cadena en MySQL con caracteres especiales.

La cadena para insertar se ve así:

macaddress_eth0;00:1E:68:C6:09:A0;macaddress_eth1;00:1E:68:C6:09:A1 

Aquí está el SQL:

 UPGRADE inventory_server set server_mac = macaddress\_eth0\;00\:1E\:68\:C6\:09\:A0\;macaddress\_eth1\;00\:1E\:68\:C6\:09\:A1' where server_name = 'myhost.fqdn.com 

Cuando ejecuto la actualización, recibo este error:

 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPGRADE inventory_server set server_mac = 'macaddress\_eth0\;00\:1E\:68\:C6\:09\' at line 1 

El código de python:

 sql = 'UPGRADE inventory_server set server_mac = \'%s\' where server_name = \'%s\'' % (str(mydb.escape_string(macs)),host) print sql try: con = mydb.connect(DBHOST,DBUSER,DBPASS,DB); with con: cur = con.cursor(mydb.cursors.DictCursor) cur.execute(sql) con.commit() except: return False 

¿Cómo puedo insertar este texto en crudo?

Esta es una de las razones por las que se supone que debes usar el enlace de parámetros en lugar de formatear los parámetros en Python.

Solo haz esto:

 sql = 'UPGRADE inventory_server set server_mac = %s where server_name = %s' 

Entonces:

 cur.execute(sql, macs, host) 

De esa manera, puedes manejar la cadena como una cadena y dejar que la biblioteca MySQL descubra cómo citarla y escapar de ella.

Además de eso, generalmente obtienes un mejor rendimiento (porque MySQL puede comstackr y almacenar en caché una consulta y reutilizarla para diferentes valores de parámetros) y evitar los ataques de inyección de SQL (una de las formas más comunes de hackearte).

Ejemplo de Python cómo insertar texto en bruto:

Crear una tabla en MySQL:

 create table penguins(id int primary key auto_increment, msg VARCHAR(4000)) 

Código Python:

 #!/usr/bin/env python import sqlalchemy from sqlalchemy import text engine = sqlalchemy.create_engine( "mysql+mysqlconnector://yourusername:yourpassword@yourhostname.com/your_database") db = engine.connect() weird_string = "~!@#$%^&*()_+`1234567890-={}|[]\;':\"" sql = text('INSERT INTO penguins (msg) VALUES (:msg)') insert = db.execute(sql, msg=weird_string) db.close() 

Ejecutalo, examina la salida:

 select * from penguins 1 ~!@#$%^&*()_+`1234567890-={}|[]\;\':" 

Ninguno de esos personajes fueron interpretados en el inserto.

Aunque también creo que se debería usar la vinculación de parámetros, también hay esto:

 >>> 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'