Usando declaraciones preparadas con mysql en python

Estoy tratando de usar SQL con sentencias preparadas en Python. Python no tiene su propio mecanismo para esto, así que trato de usar SQL directamente:

sql = "PREPARE stmt FROM ' INSERT INTO {} (date, time, tag, power) VALUES (?, ?, ?, ?)'".format(self.db_scan_table) self.cursor.execute(sql) 

Luego, más tarde, en el bucle:

 sql = "EXECUTE stmt USING \'{}\', \'{}\', {}, {};".format(d, t, tag, power) self.cursor.execute(sql) 

Y en el bucle me sale:

 MySQL Error [1064]: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2014-12-25', '12:31:46', 88000000, -6.64' at line 1 

¿Que esta pasando?

El uso de declaraciones preparadas con MySQL en Python se explica, por ejemplo, en http://zetcode.com/db/mysqlpython/ : busque en la página las Prepared statements .

En su caso, eso sería, por ejemplo:

 sql = ('INSERT INTO {} (date, time, tag, power) VALUES ' '(%s, %s, %s, %s)'.format(self.db_scan_table)) 

y luego, “en el bucle” como lo pones:

 self.cursor.execute(sql, (d, t, tag, power)) 

sin más formato de cadena: el módulo MySQLdb hace las partes de preparación y ejecución en su nombre (y puede almacenar en la memoria caché cosas para evitar que se repita el trabajo innecesariamente, etc., etc.).

Considere, dependiendo de la naturaleza del “bucle” que menciona, que es posible que una sola llamada a .execute_many (con una secuencia de tuplas como segundo argumento) pueda reemplazar al bucle completo (a menos que necesite más procesamiento). dentro de ese bucle más allá de la inserción de datos en la base de datos).

Agregado: una mejor alternativa hoy en día puede ser usar el propio Connector/Python mysql y la opción explícita prepare=True en la fábrica de .cursor() – vea http://dev.mysql.com/doc/connector-python/en/ connector-python-api-mysqlcursorprepared.html . Esto le permite tener un cursor específico sobre qué declaraciones están preparadas (con el protocolo binario “más eficiente que usar PREPARAR y EJECUTAR”, según esa página de mysql.com) y otra para las declaraciones que es mejor no prepararlas; “explícito es mejor que implícito” es, después de todo, uno de los principios en “El zen de Python” ( import this desde un indicador interactivo para leer todos esos principios). mysqldb haciendo cosas implícitamente (y parece que la versión de código abierto actual no usa declaraciones preparadas) no puede ser una architecture tan buena como la más explícita de Connector/Python .

Python soporta declaraciones preparadas:

 sql = "INSERT INTO {} (date, time, tag, power) VALUES (%s, %s, %s, %s);" sql = sql.format(self.db_scan_table) self.cursor.execute(sql, (d, t, tag, power)) 

(Debe asegurarse de que self.db_scan_table no sea vulnerable a la inyección de SQL)

Esto supone que su paramstyle es 'format' , que debería ser para MySQL .