首页 > 解决方案 > Python MySQL不刷新

问题描述

我有两个程序:一个填充和更新数据库,另一个每 10 秒从数据库中选择一次信息。

我使用 Pymysql。

当我更新数据库时,我提交数据,我可以用命令行在数据库中看到结果,但是另一个程序具有相同的输出并且没有获取新数据!

除了 之外,我还需要进行特殊查询SELECT吗?我是否需要在所有查询之前关闭连接并重新打开它?

GetData我在启动程序时创建类,get_data每 10 秒调用一次。

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()

标签: pythonmysqlpython-3.xmariadbpymysql

解决方案


为什么您没有看到更新:

该行为的原因是 InnoDB 的默认隔离级别REPEATABLE READ。使用 REPEATABLE READ,第一个非锁定 SELECT 会建立一个快照,表示该时间点的数据。所有连续的非锁定 SELECT 都从同一个快照中读取。从其他事务对数据库的更新不会反映在该快照中,因此保持透明。

提交事务(或关闭事务并创建一个新事务)将导致在下一个查询中创建一个新快照,表示该时间点数据库中的数据。这就是 MySQL 如何将Consistent Nonlocking Reads作为其ACID合规策略的一部分来实现的。

为什么with self.conn有效以及它的作用:

在 PyMySQL 中,有两个(相关的)上下文管理器实现,一个在Cursor上(或多或少“记录”),一个在Connection上(可以在代码中找到:D)。

当您使用with self.conn.cursor() as cursor:它时,游标的实现是有效的。进入返回的上下文( on方法返回self的游标对象);离开上下文最终关闭了该游标。对交易没有影响。cursor()self.conn

使用with self.conn as cursor它时,连接的实现是有效的。进入上下文从调用返回光标self.cursor();离开上下文会在事务上做一个commit或。rollback游标也隐式关闭。

因此,在离开连接实现的上下文时的隐式调用self.commit会使事务中的现有快照“过期”,并强制在循环的下一次迭代中创建一个新快照,该迭代可能包含您的插入,只要它们的提交已在创建所述新快照之前完成。


推荐阅读