代码之家  ›  专栏  ›  技术社区  ›  Nathan Wailes

SQLAlchemy会话对象没有看到数据库的更改?

  •  0
  • Nathan Wailes  · 技术社区  · 6 年前

    我在pythonany上有一个网站,它使用Flask和Flask-SQLAlchemy连接到MySQL数据库。用户可以使用网站将保存到数据库的任务作为表中的记录进行排队,然后一个单独的计划任务(Python程序)检查数据库并处理每个未处理的记录。

    我遇到的问题是,计划任务的db查询似乎只有在第一次运行时才能找到新记录,但是如果我随后使用网站添加新任务,仍在运行的计划任务的循环db查询(每5秒)似乎无法检测到新记录。

    你知道这里会发生什么吗?

    下面是bash文件正在运行的代码:

    def generate_any_pending_videos():
        unfinished_videos = db.session.query(Video)\
                                      .filter(~Video.status.has(VideoStatus.status.in_(['Error', 'Finished', 'Video deleted'])))\
                                      .order_by(Video.datetime_created)\
                                      .all()
        for video in unfinished_videos:
            try:
                logging.info("Attempting to create video for video %d" % video.id)
                generate_video(video)
            except Exception as e:
                logging.error(str(e))
    
    
    if __name__ == '__main__':
        while True:
            generate_any_pending_videos()
            time.sleep(5)
    
    2 回复  |  直到 5 年前
        1
  •  5
  •   Miguel Garcia    6 年前

    默认情况下,所有SqlAlchemy查询都在事务内部运行 http://docs.sqlalchemy.org/en/latest/orm/session_transaction.html . 这就是为什么您只能在脚本的第一个调用中获取新数据。因为在事务内部看到的数据不会改变,即ACID中的I,所以事务是隔离的。 在提交或回滚之后,下一个查询将启动一个新的事务,因此您将从数据库中获得新的数据。

        2
  •  4
  •   Nathan Wailes    6 年前

    找到一个解决方案:出于某种原因运行 db.session.commit() 在我的查询显示新记录之前。

    if __name__ == '__main__':
        while True:
            generate_any_pending_videos()
            time.sleep(5)
            db.session.commit()  # For some reason this is needed to be able to detect newly-created videos