如何在Sqlalchemy orm会话中正确禁用缓存?

2024-06-17 14:32:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个守护进程中执行线程,它循环并执行以下查询:

    try:
        newsletter = self.session.query(models.Newsletter).\
               filter(models.Newsletter.status == 'PROCESSING').\
               limit(1).one()
    except sa.orm.exc.NoResultFound:
        self.logger.debug('No PROCESSING newsletters found. Sleeping...')
        self.sleep()
        return
    # (...) more code to do with found newsletter

其中sleep方法只在配置的时间内停止该线程的执行,return语句返回到主循环。然而,我发现,如果在守护进程运行时将任何新闻稿的状态更改为“正在处理”,则不会发生任何事情,即查询仍会引发NoResultFound。但是,如果我重新启动守护进程,它会找到新闻稿。所以我知道,这个查询的结果必须被缓存。如何使缓存失效?session.expire\u全部()不起作用。我也可以在每次迭代中创建新的Session()对象,但不知道这对于系统资源是否是个好方法。在


Tags: 方法selfreturn进程modelssessionsleep线程
3条回答

SQLAlchemydoesn't cache本身。除非显式实现了缓存,like this one。在

^{}传递给您的sessionmaker,并查看{a4}。在

嗯,我已经找到答案了,你显然需要明确地去做会话.提交()以使其更新,或者需要在会话上设置autocommit=True,例如通过sessionmaker。在

sessionmaker(bind=self.engine, autocommit=True)

但是我还没有测试会话.提交()方式

所以这不是一个缓存问题,它似乎只是事务的工作方式

代码中的问题是由于数据库默认使用REPEATABLE READ isolation level造成的,因此除非您调用commit()或{}(或者按照Xeross的建议使用autocommit=True)或手动更改隔离级别,否则查询返回相同的结果。在

是的,SQLAlchemy会缓存映射对象(不是查询结果!),因为ORM模式要求每个标识对应一个对象。默认情况下,SQLAlchemy使用弱标识映射作为缓存,所以当没有对该对象的引用时,该对象将自动从会话中移除。请注意,后续查询将使用新数据更新缓存对象的状态,因此无需担心此缓存。在

相关问题 更多 >