mysql.connector.cursor.execute()静默进行,尽管commit()也没有改变

时间:2019-03-04 16:13:15

标签: python mysql

我需要在python脚本中执行某些MySQL命令,这很简单。为了进行测试,我将命令简化为:

file:

运行脚本时,用户凭据将替换为正确的信息。 该脚本的输出是

import mysql.connector

script = """
CREATE DATABASE `new_project`;

CREATE TABLE `new_project`.`category` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    UNIQUE KEY `unq_name` (`name`),
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
"""

connection = mysql.connector.connect(
    host="localhost",
    port="3306",
    user="root",
    passwd="somepassword",
)
cursor = connection.cursor()

try:
    print("begin execution")

    cursor.execute(script, multi=True)

    warnings = cursor.fetchwarnings()
    if warnings:
        for warning in warnings:
            print(warning)

    connection.commit()
    cursor.close()
    connection.close()
    print("connection closed")

except mysql.connector.Error as err:
    print(err.msg)

,无错误,警告或其他输出。未创建数据库begin execution connection closed 。当我在另一个界面中运行相同的MySQL命令时,它们将按预期工作并创建数据库和表。

我必须忽略一些非常简单的东西。

2 个答案:

答案 0 :(得分:2)

execute的{​​{3}}提到了multi=True时,该方法返回带有每个查询结果的迭代器。似乎commit()之前,查询在处理完迭代器之前不会执行任何操作。但是,CREATE语句不会产生任何结果,并且尝试迭代execute的返回值会导致异常:generator raised StopIteration。这与documentation有关,并已在8.0.13版本中修复,并支持python 3.7。

现在的解决方案是始终迭代execute的返回值,即使不需要返回数据,也要升级连接器模块。如果升级不可行,则可以捕获失败的迭代并继续。

固定代码(包括连接器模块的早期版本的部分)现在看起来像这样:

try:
    results = cursor.execute(script, multi=True)
    try:
        for result in results:
            pass
    except Exception as e:
        pass

    warnings = cursor.fetchwarnings()
    if warnings:
        for warning in warnings:
            # handle warning

    connection.commit()
    cursor.close()
    connection.close()

except mysql.connector.Error as err:
    # handle error

答案 1 :(得分:0)

尝试使用password =“ somepassword”代替passwd =“ somepassword”。并删除multi = True。它将创建警告,但仍将执行您的两条语句。