Python,“命令不同步;你现在无法运行此命令”

时间:2012-07-20 16:07:57

标签: python mysql

我有一个从Python执行的MySQL存储过程(包含在Django中)。当我尝试执行第二个语句时,我收到错误“命令不同步;你现在无法运行此命令”。此时我无法提交交易。这只是我调用程序时的一个问题。怎么办?

cursor.callproc('my_mysql_procedure', [some_id,]) 
result = cursor.fetchall()
for r in result:
    do something

cursor.execute("select * from some_table")
result = cursor.fetchall()
编辑:我被要求发布MySQL程序。我让它变得非常简单,我仍然看到同样的问题

delimiter $$
create procedure my_mysql_procedure(p_page_id int)
    begin

        select 1
        from dual; 

    end$$
delimiter ;

5 个答案:

答案 0 :(得分:48)

感谢JoshuaBoshi的回答,解决了这个问题。在调用该过程之后,我必须关闭游标并再次打开它,然后再使用它来执行另一个语句:

cursor.close() 

cursor = connection.cursor() 

可以在fetchall()后立即关闭光标。结果集仍然存在,可以循环使用。

答案 1 :(得分:12)

这样做的主要原因是在进行新查询之前未从光标获取的结果。可能有多个结果集。

要停止错误,您必须确保每次使用.nextset都使用结果集。如果它产生多个结果集 - 你甚至可能需要做一些结果集。

cursor.callproc('my_mysql_procedure', [some_id,]) 
result = cursor.fetchall()
for r in result:
    do something
cursor.nextset()
cursor.execute("select * from some_table")
result = cursor.fetchall()

就我而言,我发现这实际上可以指示sql查询中的其他问题,这些问题在进行后续查询之前不会被选为python错误。他们制作了多个结果集。

将此应用于我下面的示例(我看到同样的错误),

>>> import MySQLdb
>>> conn = MySQLdb.connect(passwd="root", db="test")
>>> cur = conn.cursor()
>>> cur.execute("insert into foo values (1););")
1L
>>> cur.nextset()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 107, in nextset
    nr = db.next_result()
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1

这里 - 因为解析错误(一些受信任的输入数据,其中包含代码)导致分号,然后是新语句 - 这会产生多个结果集。它不会为此语句产生错误,但会对下一个尝试在游标上运行命令的错误产生错误。

我已经制作了一个github回购 - https://github.com/odmsolutions/mysql_python_out_of_sync_demo - 来演示和测试这个。


原始答案: 请查看https://github.com/farcepest/MySQLdb1/issues/28,详细了解我如何使用3行代码可靠地重现此内容:

重现此事的最小案例: (假设您有一个空白数据库,并且只创建了与数据库的连接,称为conn)

>>> conn.query("Create table foo(bar int(11))")
>>> conn.query("insert into foo values (1););")
>>> conn.query("insert into foo values (2););")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now")

这是错误的语法生成,从错误中我无法判断这是问题。

尝试检查Bukzor建议的最后一个查询或过程 - 并尝试在原始mysql客户端中运行它以查看真正的问题。

答案 2 :(得分:3)

这不是python问题,而是mysql问题。从perl做同样的事情你会得到同样的错误。一般情况下,当我运行mysql控制台,然后从另一个控制台终止它,然后尝试从被杀死的控制台运行查询时,我会看到该消息。

某些事情正在扼杀你的言论之间的联系。这可能是您手术中的错误。检查你的mysql错误日志。

答案 3 :(得分:2)

运行以下Python(2.7)代码时遇到此错误:

  def _execute(self, query, params, is_destructive):
try:
  cursor = self.con.cursor()
  cursor.execute(query, params)
  if is_destructive:
    self.con.commit()
  return cursor.fetchall()
finally:
  cursor.close()

问题源于self.con.commit()调用。我们是防御性的,编码在关闭游标之前提交破坏性(写入)操作。 MySql不喜欢这个。删除调用的commit()解决了问题,脚本仍然通过cursor.fetchall()

执行

答案 4 :(得分:0)

由于我现在已经在Google上搜索过几次,遇到了同样的SO问题(在此),并且没有答案是有帮助的,因此以下是对自己的建议:

此错误是MySQL无法获取响应的来源。就是说,我们发送了请求,但又收到了一些东西,但并不在意读取它。

req = "UPDATE data SET h1='qwertyuioasdasdasda' WHERE id=1;commit;"

就我而言,删除commit后,我可以看到此错误:

Warning: (1265L, "Data truncated for column 'h1' at row 1")

它之所以被提出是因为我试图写h1,对于数据类型来说太长了。但是,commit阻止我取回此信息。