如何避免MySQLdb的"命令不同步;您现在无法运行此命令"(2014)异常

Dar*_*zak 15 python mysql

下面的代码,使用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;" )
Run Code Online (Sandbox Code Playgroud)

在执行第二个查询期间引发异常.正如我所读到的,异常通常是由MySQL的C API实现的限制引起的,这种实现不允许并发查询执行.

如果我在上面两个查询之间重新创建游标对象,问题就解决了,但不幸的是,解决方案对我来说似乎并不完美.我有一个非常简单的数据库连接和查询执行的abstration,并且不希望在每次查询执行后重新创建游标(据我所知)提交当前事务并可能有其他副作用.

因此,我的问题是:避免这种例外的其他方法是什么?如何准备游标对象以执行下一个查询?也许Python DB API有一些预期的方法,在使用其他数据库接口时会相对中立,并且在MySQLdb的情况下会解决这个问题吗?

在此先感谢您的时间和帮助:)

编辑: 在我发布问题后,我开始阅读Python DB API规范,阅读有关游标销毁的副作用(我不太确定事务提交:))我发现以下,替代解决方法:

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 );
Run Code Online (Sandbox Code Playgroud)

问题是我不知道它做了什么(它返回1两次,None之后).我应该深入这个方向吗?我的意思是,我应该理解这些集合的概念来找到我的问题的解决方案吗?

Gle*_*ard 10

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()
Run Code Online (Sandbox Code Playgroud)

在我看来,这是Python的DB-API的一个严重的,明显的设计错误,使得在事务之外执行命令并对事务进行适当控制是一个严重的麻烦,例如.使用像SQLite这样的东西BEGIN EXCLUSIVE TRANSACTION.就好像没有真正数据库经验的人被允许设计API一样......

  • +1,或者您可以在第一个位置将__autocommit__设置为true,默认情况下禁用; 像这样`cursor.connection.autocommit(True)`,. (7认同)