Python MySQL 不刷新
Python MySQL not refreshing
我有两个程序:一个填充和更新数据库,另一个每 10 秒从数据库中选择一次信息。
我用的是Pymysql。
当我更新数据库时,我提交了数据,我可以使用命令行在数据库中看到结果,但是另一个程序有相同的输出并且没有获取新数据!
除了SELECT
,我还需要做一个特殊的查询吗?
在所有查询之前是否需要关闭连接并重新打开它?
我在启动程序时创建 GetData
class 并且每 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()
为什么你没有看到更新:
该行为的原因是 InnoDB 的默认隔离级别 REPEATABLE READ。使用 REPEATABLE READ,第一个非锁定 SELECT 建立一个代表该时间点数据的快照。所有连续的非锁定 SELECTs 从同一快照读取。其他事务对数据库的更新不会反映在该快照中,因此保持透明。
提交事务(或关闭它并创建一个新事务)将导致使用下一个查询创建一个新快照,代表数据库中 that 点的数据及时。这就是 MySQL 实施 Consistent Nonlocking Reads as part of their ACID 合规策略的方式。
为什么 with self.conn
有效以及它的作用:
在 PyMySQL 中,有两个(相关的)contextmanager 实现,一个在 Cursor (more or less 'documented') and one on the Connection 上(可以在代码中找到 :D)。
当您使用 with self.conn.cursor() as cursor:
时,游标的实现才有效。进入返回的上下文self
(从self.conn
上的cursor()
方法返回的游标对象);离开上下文最终关闭了那个游标。对交易没有影响。
当使用 with self.conn as cursor
时,有效的是连接的实现。从调用 self.cursor()
进入上下文 returns 光标;离开上下文会对事务执行 commit
或 rollback
。游标也隐式关闭。
因此,在离开连接实现的上下文时对 self.commit
的隐式调用 'expires' 事务中的现有快照,并强制在循环的下一次迭代中创建一个新快照,其中可能包含您的插入内容,只要它们的提交在创建所述新快照之前已完成。
我在
之后添加 self.conn.commit()
解决了同样的问题
cursor.fetchall()
我有两个程序:一个填充和更新数据库,另一个每 10 秒从数据库中选择一次信息。
我用的是Pymysql。
当我更新数据库时,我提交了数据,我可以使用命令行在数据库中看到结果,但是另一个程序有相同的输出并且没有获取新数据!
除了SELECT
,我还需要做一个特殊的查询吗?
在所有查询之前是否需要关闭连接并重新打开它?
我在启动程序时创建 GetData
class 并且每 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()
为什么你没有看到更新:
该行为的原因是 InnoDB 的默认隔离级别 REPEATABLE READ。使用 REPEATABLE READ,第一个非锁定 SELECT 建立一个代表该时间点数据的快照。所有连续的非锁定 SELECTs 从同一快照读取。其他事务对数据库的更新不会反映在该快照中,因此保持透明。
提交事务(或关闭它并创建一个新事务)将导致使用下一个查询创建一个新快照,代表数据库中 that 点的数据及时。这就是 MySQL 实施 Consistent Nonlocking Reads as part of their ACID 合规策略的方式。
为什么 with self.conn
有效以及它的作用:
在 PyMySQL 中,有两个(相关的)contextmanager 实现,一个在 Cursor (more or less 'documented') and one on the Connection 上(可以在代码中找到 :D)。
当您使用 with self.conn.cursor() as cursor:
时,游标的实现才有效。进入返回的上下文self
(从self.conn
上的cursor()
方法返回的游标对象);离开上下文最终关闭了那个游标。对交易没有影响。
当使用 with self.conn as cursor
时,有效的是连接的实现。从调用 self.cursor()
进入上下文 returns 光标;离开上下文会对事务执行 commit
或 rollback
。游标也隐式关闭。
因此,在离开连接实现的上下文时对 self.commit
的隐式调用 'expires' 事务中的现有快照,并强制在循环的下一次迭代中创建一个新快照,其中可能包含您的插入内容,只要它们的提交在创建所述新快照之前已完成。
我在
之后添加self.conn.commit()
解决了同样的问题
cursor.fetchall()