python - 在标识映射之外强制使用 sqlalchemy ORM get()

标签 python orm sqlalchemy

背景

get() 方法在 SQLAlchemy 的 ORM 中很特殊,因为它会在向数据库发出 SQL 查询之前尝试从身份映射返回对象(参见 documentation)。

这对性能有好处,但可能会导致分布式应用程序出现问题,因为一个对象可能已被另一个进程修改,因此本地进程无法知道该对象是脏的,并且会继续从调用 get() 时的身份映射。


问题

我如何强制 get() 忽略标识映射并每次都向数据库发出调用?


示例

  • 我在 ORM 中定义了一个 Company 对象。
  • 我有一个 price_updater() 进程,它每秒更新所有 Company 对象的 stock_price 属性。
  • 我有一个 buy_and_sell_stock() 过程,偶尔买卖股票。
    • 现在,在这个过程中,我可能加载了一个 microsoft = Company.query.get(123) 对象。
    • 几分钟后,我可能会再次调用 Company.query.get(123)。从那时起股票价格发生了变化,但我的 buy_and_sell_stock() 过程并不知道变化,因为它发生在另一个过程中。
    • 因此,get(123) 调用从 session 的标识映射中返回了 Company 的陈旧版本,这是一个问题。

我搜索了 SO(在 [sqlalchemy] 标签下)并阅读了 SQLAlchemy 文档以尝试找出如何执行此操作,但还没有找到方法。

最佳答案

使用 session.expire(my_instance)将导致在访问时重新选择数据。但是,即使您使用 expire(或 expunge),下一次提取的数据也将基于事务隔离级别。查看PostgreSQL docs on isolations levels (它也适用于其他数据库)和 SQLAlchemy docs on setting isolation levels .

您可以使用 in 测试实例是否在 session 中:my_instance in session .

您可以 use filter instead of get to bypass the cache , 但它仍然具有相同的隔离级别限制。

Company.query.filter_by(id=123).one()

关于python - 在标识映射之外强制使用 sqlalchemy ORM get(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29223734/

相关文章:

mysql - CakePHP 显示作者不在作者表中的所有书籍

asp.net-mvc-3 - 在 Entity Framework 中使用数据库优先方法

python - 使用sqlalchemy从postgis数据库获取经度和纬度

python - 在需要 float 的 python3 中使用 ctypes 时得到 'nan'

python - OpenCV 灰度图像中轮廓图的平均强度

python - Django - 电子邮件发送两次

python - 在 Python 中使用 Fernet 进行对称加密 - 主密码用例

python - keras.backend的clear_session()方法没有清理拟合数据

python - Django 按小时分组

python - 如何使用sqlalchemy获取在sqlite中创建的数据库的sql转储