代码之家  ›  专栏  ›  技术社区  ›  my_name

Python MySQL不刷新

  •  -1
  • my_name  · 技术社区  · 8 年前

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

    我使用Pymysql。

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

    我需要做一个特殊的查询吗 SELECT 在所有查询之前,是否需要关闭连接并重新打开它?

    我创造了 GetData 课程开始时 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()
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   shmee    8 年前

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

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

    为什么? with self.conn 工作原理:

    在PyMySQL中,有两个(相关的)contextmanager实现,一个在 Cursor (或多或少“记录在案”)和 Connection (可在代码中找到:D)。

    with self.conn.cursor() as cursor: 是游标的实现生效了。输入返回的上下文 self (从 cursor() self.conn ); 离开上下文最终关闭了光标。它对交易没有影响。

    with self.conn as cursor 有效的是连接的实现。输入上下文将返回调用 self.cursor() commit rollback 在交易中。光标也是隐式关闭的。

    所以,对 self.commit 当离开连接实现的上下文时,事务中的现有快照将“过期”,并强制在循环的下一次迭代中创建一个新的快照,该循环可能包含插入项,只要它们的提交在创建所述新快照之前完成。