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

时间:2018-09-03 21:51:52

标签: python flask flask-sqlalchemy pythonanywhere

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

我遇到的问题是计划任务的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)

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

找到一个解决方法:出于某种原因,在我的查询显示新记录之前运行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

答案 2 :(得分:0)

您可以在 sqlalchemy 引擎中更改隔离级别:

engine = create_engine(db_path, execution_options={"isolation_level": "READ COMMITTED"})

那是mysql默认配置的问题。