Способы избежать 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...