Способы избежать MySQLdb "Команды не синхронизированы, вы не можете запустить эту команду сейчас" (2014) исключение

Следующий код, используя python 2.6.6 и MySQLdb 1.2.2, приводит к невозможности синхронизации команд; вы не можете запустить эту команду теперь исключение 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;" )

Исключение возникает во время выполнения второго запроса. Как я читал, исключение обычно вызвано ограничениями реализации API MySQL C, которые запрещают выполнение одновременных запросов.

Если я воссоздаю объект курсора между двумя вышеуказанными запросами, проблема будет решена, но, к сожалению, решение для меня не кажется идеальным. У меня очень простое воздержание от подключения к базе данных и выполнения запроса, и я бы предпочел не воссоздавать курсор после выполнения каждого запроса, как он будет (насколько я понимаю), совершить текущую транзакцию и потенциально иметь другие побочные эффекты.

Поэтому мой вопрос: каковы другие способы избежать этого исключения? Как подготовить объект курсора для выполнения следующего запроса? Возможно, существует некоторый метод, ожидаемый API-интерфейсом Python DB, который был бы относительно нейтрален при использовании других интерфейсов баз данных и будет работать над проблемой в случае MySQLdb?

Заранее благодарим за ваше время и помощь:)

Edit: После того, как я разместил этот вопрос, я начал читать спецификацию API DB Python, чтобы прочитать о побочных эффектах уничтожения курсора (я не уверен в транзакции больше:)), и я нашел следующую альтернативную работу:

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 );

Проблема в том, что я не знаю, что она делает (после этого возвращается 1 два раза и None). Должен ли я копаться в этом направлении? Я имею в виду, должен ли я понимать концепцию этих множеств, чтобы найти решение моей проблемы?

Ответы

Ответ 1

DB-API пытается самостоятельно обрабатывать транзакции, запуская транзакцию по первой команде и имея свой собственный вызов API для ее фиксации, поэтому:

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()

На мой взгляд, это серьезная, вопиющая ошибка дизайна Python DB-API, что делает серьезную проблему для выполнения команд за пределами транзакций и для правильного управления транзакциями, например. использовать такие вещи, как SQLite BEGIN EXCLUSIVE TRANSACTION. Как будто кому-то, у кого нет реального опыта работы с базами данных, было разрешено создавать API...