Formas de evitar los comandos de MySQLdb desincronizados; no puedes ejecutar este comando ahora ”(2014) excepción

Siguiendo el código, el uso de python 2.6.6 y MySQLdb 1.2.2 hace que los comandos no estén sincronizados; no puede ejecutar este comando ahora excepción de MySQLdb:

import MySQLdb conn = MySQLdb.connect( db="test", user="root" ) cursor = conn.cursor( MySQLdb.cursors.DictCursor ) cursor.execute( "BEGIN; CREATE TABLE t1 ( t1_id INT PRIMARY KEY AUTO_INCREMENT ); COMMIT;" ) cursor.execute( "BEGIN; CREATE TABLE t2 ( t2_id INT PRIMARY KEY AUTO_INCREMENT ); COMMIT;" ) 

La excepción se produce durante la ejecución de la segunda consulta. Mientras leo, la excepción generalmente es causada por limitaciones de la implementación de la API C de MySQL, que no permiten la ejecución de consultas concurrentes.

Si vuelvo a crear el objeto del cursor entre las dos consultas anteriores, el problema está resuelto, pero desafortunadamente la solución no me parece perfecta. Tengo una abstracción muy simple sobre la conexión de la base de datos y la ejecución de consultas y preferiría no volver a crear el cursor después de cada ejecución de la consulta, ya que (en la medida en que lo entiendo) comprometerá la transacción actual y posiblemente tenga otros efectos secundarios.

Por lo tanto, mi pregunta es: ¿Cuáles son otras formas de evitar esta excepción? ¿Cómo preparar el objeto del cursor para la ejecución de la siguiente consulta? ¿Tal vez la API de la base de datos de Python espera algún método que sea relativamente neutral al usar otras interfaces de base de datos y solucionará el problema en el caso de MySQLdb?

Gracias de antemano por su tiempo y ayuda 🙂

Edición: Después de publicar la pregunta, comencé a leer la especificación de la API de Python DB para leer sobre los efectos secundarios de la destrucción del cursor (ya no estoy tan seguro acerca de la confirmación de transacción :)) y encontré una alternativa alternativa:

 cursor.execute( "BEGIN; CREATE TABLE t1 ( t1_id INT PRIMARY KEY AUTO_INCREMENT ); COMMIT;" ) while cursor.nextset() is not None: pass cursor.execute( "BEGIN; CREATE TABLE t2 ( t2_id INT PRIMARY KEY AUTO_INCREMENT ); 

El problema es que no sé qué hace (devuelve 1 dos veces y None después de eso). ¿Debo cavar en esta dirección? Quiero decir, ¿debo entender el concepto de estos conjuntos para encontrar una solución a mi problema?

DB-API intenta manejar las transacciones por su cuenta, iniciando una transacción con el primer comando y teniendo su propia llamada a la API para confirmarla, por lo que:

 cursor.execute( "CREATE TABLE t1 ( t1_id INT PRIMARY KEY AUTO_INCREMENT )" ) cursor.commit() cursor.execute( "CREATE TABLE t2 ( t2_id INT PRIMARY KEY AUTO_INCREMENT )" ) cursor.commit() 

En mi opinión, este es un error grave y evidente del diseño de la API de base de datos de Python, lo que hace que sea un gran problema ejecutar comandos fuera de las transacciones y tener el control adecuado sobre las transacciones, por ejemplo. para usar cosas como SQLite’s BEGIN EXCLUSIVE TRANSACTION . Es como si a alguien sin experiencia en bases de datos reales se le permitiera diseñar la API …