造成这种情况的主要原因是在进行新查询之前未从游标中获取结果。可能有多个结果集。
要停止错误,您必须确保每次使用 .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 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")
这是生成的错误语法,从错误中我无法判断这是问题所在。
尝试按照 Bukzor 的建议检查最后一个查询或过程 - 并尝试在原始 mysql 客户端中运行它以查看真正的问题。