【问题标题】:How to disable caching correctly in Sqlalchemy orm session?如何在 Sqlalchemy orm 会话中正确禁用缓存?
【发布时间】:2011-05-16 04:32:05
【问题描述】:

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

    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 缓存?它很可能是一个数据库锁,它在查询完成之前阻止更新,因为查询取出了错误的锁。你有缓存的证据吗?或者这是一个猜测?
  • 我没有任何证据。只是一个猜测。也许缓存是在其他地方完成的。使用 rollback() 似乎在这里工作。
  • 更有可能是不是缓存,而是锁定。
  • 我在这里遇到了完全相同的问题,我的结果由于某种原因没有更新,输出保持不变,奇怪的是它甚至发生在我尚未获取的记录上:/这是香草 SQLAlchemy

标签: python sql multithreading caching sqlalchemy


【解决方案1】:

SQLAlchemy doesn't cache 本身。除非你明确实现了缓存,like this one

echo=True 传递给您的sessionmaker 并查看logging output

【讨论】:

【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    嗯,我已经找到了答案,您显然需要明确执行 session.commit() 以使其更新,或者您需要在会话上设置 autocommit=True,例如通过 sessionmaker。

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

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

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

    【讨论】:

      【解决方案4】:

      不要使用 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()

      【讨论】:

        猜你喜欢
        • 2012-04-29
        • 1970-01-01
        • 1970-01-01
        • 2022-06-24
        • 2016-05-18
        • 2012-08-16
        • 2016-06-06
        • 1970-01-01
        相关资源
        最近更新 更多