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

use*_*003 33 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()
Run Code Online (Sandbox Code Playgroud)

编辑:我被要求发布MySQL程序.我让它变得非常简单,我仍然看到同样的问题

delimiter $$
create procedure my_mysql_procedure(p_page_id int)
    begin

        select 1
        from dual; 

    end$$
delimiter ;
Run Code Online (Sandbox Code Playgroud)

use*_*003 53

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

cursor.close() 

cursor = connection.cursor() 
Run Code Online (Sandbox Code Playgroud)

光标可以在之后立即关闭fetchall().结果集仍然存在并且可以循环.

  • 这没有意义 - 有谁知道为什么? (3认同)
  • 另外需要指出的是,MySQLDB/SQLAlchemy 不能处理每个字符串超过一个的查询。即“select 1; select 1”会导致这个问题。更糟糕的是,*评论* 也可能导致这种情况!认真的!:“选择 1;——随便” (3认同)
  • mycursor.close() 然后 mycursor = mydb.cursor() 给我错误...“mysql.connector.errors.ProgrammingError:光标未连接”。 (2认同)

Dan*_*ple 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()
Run Code Online (Sandbox Code Playgroud)

在我的例子中,我发现这实际上可以指示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
Run Code Online (Sandbox Code Playgroud)

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

我已经制作了一个github repo - 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")
Run Code Online (Sandbox Code Playgroud)

这是生成的错误语法,从错误中我无法分辨出这是问题所在.

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