我需要在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命令时,它们将按预期工作并创建数据库和表。
我必须忽略一些非常简单的东西。
答案 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。它将创建警告,但仍将执行您的两条语句。