Python mysql.connector cursor.execute() 和 connection.commit() 不在循环中工作
Python mysql.connector cursor.execute() and connection.commit() not working in a loop
尝试使用 for-loop
自动处理 MySQL 中的表
from mysql.connector import connect, Error
def main():
try:
with connect(host="host", user="user",password="password") as connection:
connection.autocommit = True
no_pk_tables_query = """
select tab.table_schema as database_name,
tab.table_name
from information_schema.tables tab
left join information_schema.table_constraints tco
on tab.table_schema = tco.table_schema
and tab.table_name = tco.table_name
and tco.constraint_type = 'PRIMARY KEY'
where tco.constraint_type is null
and tab.table_schema not in('mysql', 'information_schema',
'performance_schema', 'sys')
and tab.table_type = 'BASE TABLE'
order by tab.table_schema,
tab.table_name;
"""
tables_to_cure = []
with connection.cursor() as cursor:
cursor.execute(no_pk_tables_query)
for table in cursor:
tables_to_cure.append(table[1])
print(table[1])
for s_table in tables_to_cure:
cure = """
USE mission_impossible;
ALTER TABLE `{}` MODIFY `ID` int(18) NOT NULL auto_increment PRIMARY KEY;
""".format(s_table)
cursor.execute(cure)
print("Cured {}".format(s_table))
except Error as e:
print(e)
finally:
print("End")
main()
然后我得到:
quote 2014 (HY000): 命令不同步;你现在不能运行这个命令
如果我在 cursor.execute() 之后的 for 循环内添加 connection.commit() 我会得到:
_mysql_connector.MySQLInterfaceError:命令不同步;你现在不能运行这个命令
这是否意味着我必须在循环内使用新连接而不是游标?
我查了一下,发现了一些像 fetchall()
和 nextset()
这样的方法,但它们似乎除了简单地刷新当前游标数据之外还做了其他事情。
使用 connection.autocommit = True
似乎也不起作用,因为发生了同样的错误。
使用 sleep()
之类的东西也无济于事。
我在这里做错了什么?
编辑
摆脱 try/except 没有帮助:
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/connection_cext.py", line 523, in cmd_query
self._cmysql.query(query,
_mysql_connector.MySQLInterfaceError: Commands out of sync; you can't run this command now
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "db.py", line 40, in <module>
main()
File "db.py", line 36, in main
cursor.execute(cure)
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/cursor_cext.py", line 269, in execute
result = self._cnx.cmd_query(stmt, raw=self._raw,
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/connection_cext.py", line 528, in cmd_query
raise errors.get_mysql_exception(exc.errno, msg=exc.msg,
mysql.connector.errors.DatabaseError: 2014 (HY000): Commands out of sync; you can't run this command now
固定:
看来我终于弄明白了,需要使用 fetchall()
从游标中获取结果,而不是直接将游标作为迭代器进行寻址。
with connection.cursor() as cursor:
cursor.execute(no_pk_tables_query)
rows = cursor.fetchall()
with connection.cursor() as cursor:
for table in rows:
try:
print(table[1])
cure = """
ALTER TABLE `{}` MODIFY `ID` int(18) NOT NULL auto_increment PRIMARY KEY;
""".format(table[1])
cursor.execute(cure)
res = cursor.fetchall()
print(res)
except Error as e:
print(e)
谢谢大家
下面是一些示例代码,显示了“命令不同步”错误是如何发生的:
from mysql.connector import connect, Error
# replace asterisks in the CONFIG dictionary with your data
CONFIG = {
'user': '*',
'password': '*',
'host': '*',
'database': '*',
'autocommit': False
}
try:
with connect(**CONFIG) as conn:
try:
with conn.cursor() as cursor:
cursor.execute('select * from ips')
# cursor.fetchall()
finally:
conn.commit()
except Error as e:
print(e)
解释:
代码 select 是来自名为“ips”的 table 的所有行,其内容与此处无关。
现在,请注意我们不会尝试获取行集(fetchall 已被注释掉)。然后我们尝试提交事务(即使未对 table 进行任何更改)。
这会导致“命令不同步”错误。
但是,如果我们取出注释行并获取行集(fetchall),则不会出现此问题。
显式获取行集等同于遍历游标。
如果我们将自动提交参数更改为 True 并删除显式 commit(),我们会收到另一个错误:-“找到未读结果”。
换句话说,似乎 MySQL 要求 您在 select 任何时候获取行集(或遍历游标)!
请注意,即使启用了自动提交 (True),也允许显式调用 commit()
解决方案:
要么确保客户端应用程序在 SELECT 之后遍历整个游标,要么在 CONFIG 字典中添加:'consume_results': True
尝试使用 for-loop
自动处理 MySQL 中的表from mysql.connector import connect, Error
def main():
try:
with connect(host="host", user="user",password="password") as connection:
connection.autocommit = True
no_pk_tables_query = """
select tab.table_schema as database_name,
tab.table_name
from information_schema.tables tab
left join information_schema.table_constraints tco
on tab.table_schema = tco.table_schema
and tab.table_name = tco.table_name
and tco.constraint_type = 'PRIMARY KEY'
where tco.constraint_type is null
and tab.table_schema not in('mysql', 'information_schema',
'performance_schema', 'sys')
and tab.table_type = 'BASE TABLE'
order by tab.table_schema,
tab.table_name;
"""
tables_to_cure = []
with connection.cursor() as cursor:
cursor.execute(no_pk_tables_query)
for table in cursor:
tables_to_cure.append(table[1])
print(table[1])
for s_table in tables_to_cure:
cure = """
USE mission_impossible;
ALTER TABLE `{}` MODIFY `ID` int(18) NOT NULL auto_increment PRIMARY KEY;
""".format(s_table)
cursor.execute(cure)
print("Cured {}".format(s_table))
except Error as e:
print(e)
finally:
print("End")
main()
然后我得到:
quote 2014 (HY000): 命令不同步;你现在不能运行这个命令
如果我在 cursor.execute() 之后的 for 循环内添加 connection.commit() 我会得到:
_mysql_connector.MySQLInterfaceError:命令不同步;你现在不能运行这个命令
这是否意味着我必须在循环内使用新连接而不是游标?
我查了一下,发现了一些像 fetchall()
和 nextset()
这样的方法,但它们似乎除了简单地刷新当前游标数据之外还做了其他事情。
使用 connection.autocommit = True
似乎也不起作用,因为发生了同样的错误。
使用 sleep()
之类的东西也无济于事。
我在这里做错了什么?
编辑
摆脱 try/except 没有帮助:
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/connection_cext.py", line 523, in cmd_query
self._cmysql.query(query,
_mysql_connector.MySQLInterfaceError: Commands out of sync; you can't run this command now
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "db.py", line 40, in <module>
main()
File "db.py", line 36, in main
cursor.execute(cure)
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/cursor_cext.py", line 269, in execute
result = self._cnx.cmd_query(stmt, raw=self._raw,
File "/usr/local/lib/python3.8/dist-packages/mysql/connector/connection_cext.py", line 528, in cmd_query
raise errors.get_mysql_exception(exc.errno, msg=exc.msg,
mysql.connector.errors.DatabaseError: 2014 (HY000): Commands out of sync; you can't run this command now
固定:
看来我终于弄明白了,需要使用 fetchall()
从游标中获取结果,而不是直接将游标作为迭代器进行寻址。
with connection.cursor() as cursor:
cursor.execute(no_pk_tables_query)
rows = cursor.fetchall()
with connection.cursor() as cursor:
for table in rows:
try:
print(table[1])
cure = """
ALTER TABLE `{}` MODIFY `ID` int(18) NOT NULL auto_increment PRIMARY KEY;
""".format(table[1])
cursor.execute(cure)
res = cursor.fetchall()
print(res)
except Error as e:
print(e)
谢谢大家
下面是一些示例代码,显示了“命令不同步”错误是如何发生的:
from mysql.connector import connect, Error
# replace asterisks in the CONFIG dictionary with your data
CONFIG = {
'user': '*',
'password': '*',
'host': '*',
'database': '*',
'autocommit': False
}
try:
with connect(**CONFIG) as conn:
try:
with conn.cursor() as cursor:
cursor.execute('select * from ips')
# cursor.fetchall()
finally:
conn.commit()
except Error as e:
print(e)
解释:
代码 select 是来自名为“ips”的 table 的所有行,其内容与此处无关。
现在,请注意我们不会尝试获取行集(fetchall 已被注释掉)。然后我们尝试提交事务(即使未对 table 进行任何更改)。
这会导致“命令不同步”错误。
但是,如果我们取出注释行并获取行集(fetchall),则不会出现此问题。
显式获取行集等同于遍历游标。
如果我们将自动提交参数更改为 True 并删除显式 commit(),我们会收到另一个错误:-“找到未读结果”。
换句话说,似乎 MySQL 要求 您在 select 任何时候获取行集(或遍历游标)!
请注意,即使启用了自动提交 (True),也允许显式调用 commit()
解决方案:
要么确保客户端应用程序在 SELECT 之后遍历整个游标,要么在 CONFIG 字典中添加:'consume_results': True