我有两个程序:一个用于填充和更新数据库,另一个用于每10秒从数据库中选择信息。
我使用Pymysql。
当我更新数据库时,我提交了数据,我可以使用命令行在数据库中查看结果,但是另一个程序具有相同的输出,并且不会获取新数据!
除了SELECT
之外,还需要进行特殊查询吗?
在所有查询之前,我需要关闭连接并重新打开它吗?
我在启动程序时创建了GetData
类,并且每10秒调用一次get_data
。
class GetData:
def __init__(self):
self.conn = pymysql.connect(host='localhost', user='root', password='', db='mydb', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
def get_data(self, data):
with self.conn.cursor() as cursor:
self.sql = "SELECT id_data, somedata FROM mytable WHERE (%s = 'example');"
cursor.execute(self.sql, (data,))
return cursor.fetchall()
def close_conn(self):
self.conn.close()
填充数据库的程序:
class FillDb:
def __init__(self):
self.conn = pymysql.connect(host='localhost', user='root', password='', db='mydb', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
#added this line but doesen't help!
self.conn.autocommit(True)
def add_in_db(self, data):
with self.conn.cursor() as cursor:
self.sql = "INSERT INTO mytable (somedata) VALUES (%s);"
cursor.execute(self.sql, (data,))
self.conn.commit()
答案 0 :(得分:1)
为什么看不到更新:
此问题的原因是InnoDB的默认隔离级别REPEATABLE READ。使用REPEATABLE READ,第一个非锁定SELECT建立一个快照,表示该时间点的数据。所有连续的非锁定SELECT都从同一快照读取。从其他事务到数据库的更新不会反映在该快照中,因此保持透明。
提交事务(或关闭它并创建一个新事务)将导致在下一个查询中创建一个新快照,该快照代表数据库中 时间点的数据。这就是MySQL在其Consistent Nonlocking Reads遵从策略中实施ACID的方式。
with self.conn
的工作原理和作用:
在PyMySQL中,有两种(相关的)contextmanager实现,一种在Cursor(或多或少的“文档化”)上,一种在Connection(可在代码:D中找到)。
使用with self.conn.cursor() as cursor:
时,实际上是游标的实现。输入返回的上下文self
(从cursor()
的{{1}}方法返回的光标对象);离开上下文最终关闭了该光标。它对交易没有影响。
使用self.conn
时,连接的实现才有效。输入上下文将使光标从调用with self.conn as cursor
返回;离开上下文会对交易产生self.cursor()
或commit
的影响。光标也隐式关闭。
因此,在离开连接实现的上下文时对rollback
的隐式调用会“使”事务中的现有快照“过期”,并在循环的下一个迭代中强制创建一个新快照,其中可能包含您的插入内容,只要它们的提交在创建所述新快照之前已完成。