mysql/connector 执行什么都不做

mysql/connector Execute does nothing

请给我任何建议,卡得很深... 这是我的代码,它什么也不做。数据库未受影响,没有错误,什么都没有

query = """DROP TABLE test;
    CREATE TABLE test (first_row text);"""
cursor.execute(query, multi=True)
db.commit()

有趣的是,查询甚至可以在第二条语句中包含语法错误,代码仍然可以毫无错误地执行。另外,如果没有 multi 则有回溯 "InterfaceError: Use multi=True when executing multiple statements"

query = """DROP TABLE test;
    CREATE TABBBBBBLE test (first_row text);"""
cursor.execute(query, multi=True)
db.commit()

分离查询完美无缺,数据库实际发生变化,因此 dbcursor 对象创建没有错误:

query1 = "DROP TABLE test"
query2 = "CREATE TABLE test (first_row text)"
cursor.execute(query1)
cursor.execute(query2)
db.commit()

这是我第一次使用 mysql/connector。服务器 mysql 刚刚使用默认设置安装。在控制台 mysql> 中,一切正常。但是 python 脚本不起作用。更糟糕的是 - 没有 TRACEBACK。 是的,我只能 运行 单个语句...但这并不好。)

知道我应该如何调试这个问题吗?

您没有看到任何回溯的原因是因为当您使用 multi=True 时返回的是 python iterator 游标,它可以处理每个语句的结果。访问查询结果(或缺少结果或错误)的最简单方法是遍历返回的 iterator 游标并获取它们相应的行或处理错误。

此外,如果您的多个查询中的第一个查询未执行table(即导致某种错误),则其余查询将不会被执行。因此,如果您尝试循环返回的 iterator,将引发异常,错误消息是 MySQL 服务器引发的错误。一般来说,查询会一直执行到有无法成功执行的查询为止,

使用您提供的代码,以下片段应作为说明:

# Multiple queries
query = """DROP TABLE test; CREATE TABLE test (first_col text)"""

# Loop through the results
for rslt in cursor.execute(query, multi=True):
    print(rslt.fetchone())

这应该引发 mysql.connector.errors.ProgrammingError 异常,因为第一个查询将不会成功执行。 但是,如果您要颠倒查询的顺序,则不会遇到任何异常,因为查询会成功执行:

query = """CREATE TABLE test (first_col text); DROP TABLE test"""

# Loop through the results
for rslt in cursor.execute(query, multi=True):
    print(rslt.fetchone())

代码应该 运行 很好,即使您会看到 None 打印出来。

一般来说,当 multi 参数设置为 True 时,保存返回的 iterator 并一次循环一个结果。当发生错误时,以下应该总是告诉你一些事情:

# Set three queries (2 good and the last one bad)
query = """CREATE TABLE test (first_col text); DROP TABLE test; select * from test"""

# Save the returned iterator in a variable
results = cursor.execute(query, multi=True)
db.commit()

# Do some looping with exception handling
while True:
    try:
        rslt = next(results)
        print(rslt.fetchall())
    except Exception as e:
        print("Error encountered: %s" % e)
        break

此代码将 运行 前两个查询成功。 table 将被创建,然后被删除。但是,第三个将失败,因为没有 table 名为 test 的查询。因此,您应该会看到类似 Error encountered: 1051 (42S02): Unknown table 'test'.

的内容

总之,您应该遍历返回的结果,以便获得结果并检查错误。 while True 和异常处理的组合在大多数情况下应该工作得很好。

关于iterators的澄清:

iterator 中的变量在调用 next() 方法时 延迟求值。这意味着如果您使用 while Truenext(results),则触发查询执行的是 next(results) 操作。但是,如果您使用 for loop,那么查询将在您循环时执行。在任何情况下,当使用 CUR.execute(query, multi=True) 时,查询仅 真正地 在循环时执行。

希望这有用。