【问题标题】:mysql/connector Execute does nothingmysql/connector Execute 什么都不做
【发布时间】:2017-11-26 20:48:28
【问题描述】:

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

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

有趣的是,查询甚至可以在第二条语句中包含语法错误,代码仍然可以正常执行。此外,如果没有multi,则会出现回溯“InterfaceError: Use multi=True when execution 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脚本不起作用。更糟糕的是 - 没有追溯。 是的,我只能运行单个语句......但这并不好。)

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

【问题讨论】:

    标签: python-3.x mysql-connector-python


    【解决方案1】:

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

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

    使用您提供的代码,以下 sn-ps 应作为说明:

    # 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())
    

    代码应该可以正常运行,即使您会看到 Nones 打印出来。

    一般来说,当使用设置为Truemulti 参数时,保存返回的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
    

    此代码将成功运行前两个查询。该表将被创建,然后被删除。但是,第三个将失败,因为将没有名为 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) 时,查询只会在循环时真正执行。

    我希望这证明有用。

    【讨论】:

    • 非常感谢这门课程!我真的很感激这一点。)但是,简单的 CUR.execute(query, multi=True) 仍然什么都不做。即使没有错误,查询中的任何语句都不会真正执行。但同样,它只有在我使用带有 fetchone() 调用的循环时才会执行!当 fetchone() 实际执行语句时,execute(query, multi=True) simple 似乎做了一些准备。
    • 感谢您的耐心等待,现在我明白它是如何工作的了。)
    猜你喜欢
    • 2014-01-10
    • 2014-05-30
    • 2016-03-14
    • 2013-07-20
    • 2019-03-08
    • 2016-12-24
    • 2017-04-18
    • 2011-08-03
    • 2014-05-11
    相关资源
    最近更新 更多