Python连接MariaDB循环查询结果始终一致问题求助
我最近碰到个头疼的问题:另一个Python进程每60秒会更新Percentuali表,我写了个脚本每10秒循环查这个表,但每次输出的都是同一个结果!明明用HeidiSQL已经确认另一个进程的更新成功了,可我的脚本就是看不到新数据。
先说下我的环境:树莓派上跑MariaDB 10(版本号10.0.28-MariaDB-2 + b1 Raspbian testing-staging),查询代码如下:
from pickle import TRUE import ccxt import mysql.connector from datetime import datetime, date import time mydb = mysql.connector.connect( host="127.0.0.1", user="xxxxx", password="xxxxxx", database="xxxx" ) mycursor = mydb.cursor() cl = 0 while True: now = datetime.now() date_time = now.strftime("%m/%d/%Y %H:%M:%S") cls = str(cl) print (date_time + ' start ' + cls + ' cycle\n') sql= "select * from Percentuali order by Id desc limit 1" mycursor.execute(sql) myresult = mycursor.fetchone() print (myresult) # end
输出结果就一直重复这行:
(203, datetime.datetime(2022, 4, 29, 12, 15, 11), -0.0222675, None) (203, datetime.datetime(2022, 4, 29, 12, 15, 11), -0.0222675, None) ...
其实这是MySQL/MariaDB默认事务隔离级别搞的鬼!默认的REPEATABLE READ(可重复读)隔离级别下,一旦你建立了连接开启事务,在这个事务里的所有查询都会看到同一个数据快照——不管其他事务提交了多少更新,你都看不到。你的脚本里连接和游标都是在循环外面创建的,又没手动结束事务,所以一直卡在同一个事务里,自然拿不到新数据。
给你两个简单的解决办法:
方法1:每次查询后提交事务
在每次查询完数据后,加一行mydb.commit(),强制结束当前事务,这样下一次查询就会读取最新的数据快照了。另外别忘了加time.sleep(10),不然你的循环会跑疯掉:
修改后的代码片段:
cl = 0 while True: now = datetime.now() date_time = now.strftime("%m/%d/%Y %H:%M:%S") cls = str(cl) print (date_time + ' start ' + cls + ' cycle\n') sql= "select * from Percentuali order by Id desc limit 1" mycursor.execute(sql) myresult = mycursor.fetchone() print (myresult) mydb.commit() # 关键:提交当前事务 cl += 1 # 可以加上计数器,方便看循环次数 time.sleep(10) # 控制每10秒查一次
方法2:修改连接的事务隔离级别
如果你不想每次都手动提交,可以在创建连接后,把事务隔离级别改成READ COMMITTED(读已提交),这样每次查询都会自动读取其他事务已经提交的最新数据:
修改连接部分的代码:
mydb = mysql.connector.connect( host="127.0.0.1", user="xxxxx", password="xxxxxx", database="xxxx" ) # 设置事务隔离级别为读已提交 mydb.start_transaction(isolation_level='READ COMMITTED') mycursor = mydb.cursor()
额外提一句
为什么HeidiSQL能看到更新?因为HeidiSQL每次查询都是一个独立的事务,查询完自动提交,所以能拿到最新数据。你也可以每次循环都重新创建连接和游标,但这样效率会低很多,不如上面两种方法靠谱。
内容的提问来源于stack exchange,提问作者Super_Gulp

