MySQL与Python的未读结果
我使用mysql.connector来进行SQL操作。我有一个小脚本,它通过cursor.execute(...)
在游标上执行以下操作(字符串):
"use {}".format(db)
"show tables"
command = """
ALTER TABLE Object DROP PRIMARY KEY;
ALTER TABLE Object ADD `id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;
ALTER TABLE Object ADD INDEX (`uid`);"""
这个脚本会遍历几个数据库db
。
问题是,有时候我会遇到一个“发现未读结果”的错误。看起来在我运行脚本时,有时候“use mydb”会返回一个结果(cursor._have_result=True),而我并不期望会有结果。奇怪的是,如果我重新运行整个脚本,它会运行得稍微长一些,并且在处理更多数据库时会在稍后出现相同的错误。
你能建议我怎么解决或调查这个问题吗?有没有什么方法可以防止“未读结果”?
附注:当我重新运行脚本时,ALTER命令会在那些已经处理过的数据库上失败。不确定这是否会造成问题。
2 个回答
你需要在你的游标中设置 buffered = true
。想了解更多,可以查看官方的文档。
cursor = conn.cursor(buffered=True)
使用 MySQL Connector/Python 时,如果你在不同的地方使用连接对象但没有读取结果,就可能会出现 未读结果 的情况。这是没法避免的。你可以使用 buffered 选项 来立即读取结果。
正如评论中提到的,最好将语句分开,分别执行。
如果你想执行多个语句,你需要在 MySQLCursor.execute() 方法中使用 multi=True 选项(从 Connector/Python v1.0.4 开始)。实际上,如果你不使用 multi 选项而发送多个语句,会引发一个 InterfaceError。(我也怀疑这里可能有个 bug..)
补充说明:
- 与其执行 USE 命令来切换数据库,不如使用 MySQLConnection.database 属性。
你最好把更改合并成一个 ALTER TABLE 语句,比如这样:
ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT NOT NULL AUTO_INCREMENT KEY FIRST, ADD INDEX(c1)