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

zef*_*ciu 4 python sql multithreading caching sqlalchemy

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

    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
Run Code Online (Sandbox Code Playgroud)

sleep方法在配置的时间内停止执行此线程,return语句返回主循环.但是我发现,如果我在守护程序运行时将任何简报的状态更改为"正在处理",则没有任何反应,即.查询仍然引发NoResultFound.但是,如果我重新启动守护程序,它将找到新闻通讯.所以我看到,必须缓存此查询的结果.我该怎么做才能使缓存无效?session.expire_all()不起作用.我也可以在每次迭代时创建新的Session()对象,但不知道它是否是一个关于系统资源的好方法.

kni*_*tti 5

SQLAlchemy 不会自行缓存.除非您明确实现了缓存,就像这样.

传递echo=True给你sessionmaker并查看logging输出.


Den*_*ach 5

代码中的问题是由于数据库默认情况下使用REPEATABLE READ隔离级别,因此查询返回相同的结果,除非您调用commit()rollback()(或autocommit=True建议使用Xeross)或手动更改隔离级别。

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