繁体   English   中英

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

[英]How to disable caching correctly in Sqlalchemy orm session?

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

    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_all()不起作用。 我也可以在每次迭代时创建新的Session()对象,但不知道它是否是一个关于系统资源的好方法。

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

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

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

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

不要使用autocommit = True和expire_on_commit = True

for state in self.identity_map.all_states():
    state.expire(state.dict, self.identity_map._modified)

你可以:在查询之后:db.session.commit()

嗯我已经找到了答案,你显然需要明确地做session.commit()来让它更新,或者你需要在会​​话中设置autocommit = True,例如sessionmaker。

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

但是我没有测试session.commit()方式

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM