mysqlconnectorpython interfaceeerror:在执行包含多个语句的查询时,获取警告失败,get_warnings=Tru

2024-04-26 14:18:20 发布

您现在位置:Python中文网/ 问答频道 /正文

使用python3.7,我对MySQL数据库执行一个查询,其中包含多个语句,并启用get_警告:

import mysql.connector
cnx = mysql.connector.connect(host='xxx',
                                user='xxx',
                                password='xxx',
                                database='xxx',
                                use_pure=False,
                                get_warnings=True)
# Test 1, works:
cur = cnx.cursor()
cur.execute('SELECT "a"+1')
for row in cur:
    print(row)
print(cur.fetchwarnings())
cur.close()

# Test 2, InterfaceError:
cur = cnx.cursor()
for rs in cur.execute('SELECT "a"+1; SELECT 2', multi=True):
    for row in rs:
        print(row)
    print(rs.fetchwarnings())

第一个测试执行单个语句,遍历游标,获取数据,最后打印警告。预期产量:

^{pr2}$

第二个测试(您可以完全删除第一个测试)将执行print(row)一次,然后发生异常。输出:

Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\mysql\connector\connection_cext.py", line 472, in cmd_query
    raw_as_string=raw_as_string)
_mysql_connector.MySQLInterfaceError: Commands out of sync; you can't run this command now

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\mysql\connector\cursor_cext.py", line 138, in _fetch_warnings
    _ = self._cnx.cmd_query("SHOW WARNINGS")
  File "C:\Program Files\Python37\lib\site-packages\mysql\connector\connection_cext.py", line 475, in cmd_query
    sqlstate=exc.sqlstate)
mysql.connector.errors.DatabaseError: 2014 (HY000): Commands out of sync; you can't run this command now

During handling of the above exception, another exception occurred:
....etc....

有人遇到过同样的问题吗?你怎么解决的?我做错什么了?这可能是连接器的问题吗?在

我尝试过的其他方法:

  • 如果将get_warnings设置为False,则不会发生错误,并且 fetchwarnings()返回None
  • 如果从SQL代码中删除了该问题,则不会发生任何错误,fetchwarnings()将返回None
  • 回溯可以是真的还是假的
  • 在rs中使用fetchall()而不是for row会得到相同的结果
  • 许多其他变体也会产生相同的错误。在

系统:

  • 连接器版本是mysql-Connector-python-8.0.17,但是8.0.16也有相同的问题。在
  • win32上的Python3.7.3(v3.7.3:ef4ec6ed12,2019年3月25日,22:22:05)[MSC v.1916 64位(AMD64)]
  • MySQL5.7

Tags: ofinforconnectorgetmysqlexceptionxxx
1条回答
网友
1楼 · 发布于 2024-04-26 14:18:20

“命令不同步”是因为MySQL客户机接口调用的执行顺序错误。这不是连接器中的错误。这是预期的行为。在

执行第一个SELECT将返回一个MySQL resultset。在

在客户机发出另一条返回MySQL resultset的语句之前,我们必须对已经返回的resultset执行一些操作。也就是说,需要调用mysql_use_resultmysql_free_result,或者调用mysql_store_result。一旦客户机这样做了,那么客户机就可以执行另一条返回结果的SQL语句。在

(请注意,执行MySQLSHOW WARNINGS语句将返回MySQL resultset。)

同样,这是预期行为,如本文所述:

https://dev.mysql.com/doc/refman/8.0/en/commands-out-of-sync.html

mysql_free_resultmysql_store_resultmysql_use_result的引用不是特定于Python接口的;它们引用了MySQL客户机代码中的底层库例程。e、 g.https://dev.mysql.com/doc/refman/8.0/en/mysql-use-result.html


随访

我怀疑MySQL Python连接器的作者没有预料到这个用例,或者如果它是预期的,那么观察到的行为被判断为是正确的。在

为了避免这个问题,我将避免使用multii=True,并对每个SQL语句单独执行。遵循与测试1相同的模式,我们可以添加一个外部循环来遍历SQL语句

# Test 1.2
sqls = ['SELECT "a"+1', 'SELECT 2', ]
for sql in sqls:
    cur = cnx.cursor()
    cur.execute(sql)
    for row in cur:
        print(row)
    print(cur.fetchwarnings())
    cur.close()

另一个选择是避免调用fetchwarnings。这就是导致SHOW WARNINGS语句被执行的原因(只有在它首先验证警告的计数大于零之后),我们可以单独发出SHOW warnings语句,并像从SELECT返回的结果一样循环处理结果。在

^{pr2}$

相关问题 更多 >