关于在sqlalchemy会话中刷新对象

2024-06-02 05:27:18 发布

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


Tags: python
3条回答

Sessions are designed to work like this。会话B中对象的属性将保留在第一次在会话B中查询时的属性。此外,当其他会话中的对象发生更改时,SQLAlchemy不会尝试自动刷新这些对象,我也不认为尝试创建这样的对象是明智的。

您应该将每个会话的生命周期看作数据库中的单个事务。会话需要处理其对象可能过时这一事实的方式和时间并不是一个可以通过内置于SQLAlchemy中的算法(或SQLAlchemy的任何扩展)解决的技术问题:这是一个“业务”问题,您必须自己确定和编写解决方案。“正确的”响应可能是说这不是问题:如果会话B在启动时使用了数据,则会话B发生的逻辑可能是有效的。你的“问题”可能不是问题。这些文档实际上有一个entire section on when to use sessions,但是如果您希望得到一个一刀切的解决方案,它会给出一个相当严峻的响应。。。

A Session is typically constructed at the beginning of a logical operation where database access is potentially anticipated.

The Session, whenever it is used to talk to the database, begins a database transaction as soon as it starts communicating. Assuming the autocommit flag is left at its recommended default of False, this transaction remains in progress until the Session is rolled back, committed, or closed. The Session will begin a new transaction if it is used again, subsequent to the previous transaction ending; from this it follows that the Session is capable of having a lifespan across many transactions, though only one at a time. We refer to these two concepts as transaction scope and session scope.

The implication here is that the SQLAlchemy ORM is encouraging the developer to establish these two scopes in his or her application, including not only when the scopes begin and end, but also the expanse of those scopes, for example should a single Session instance be local to the execution flow within a function or method, should it be a global object used by the entire application, or somewhere in between these two.

The burden placed on the developer to determine this scope is one area where the SQLAlchemy ORM necessarily has a strong opinion about how the database should be used. The unit of work pattern is specifically one of accumulating changes over time and flushing them periodically, keeping in-memory state in sync with what’s known to be present in a local transaction. This pattern is only effective when meaningful transaction scopes are in place.

也就是说,你可以做一些事情来改变现状:

首先,您可以减少会话保持打开的时间。会话B正在查询对象,然后稍后您将对该对象(在同一会话中)执行一些操作,以使属性保持最新。一种解决方案是在单独的会话中完成第二个操作。

另一种方法是使用expire/refresh方法,如docs show。。。

# immediately re-load attributes on obj1, obj2
session.refresh(obj1)
session.refresh(obj2)

# expire objects obj1, obj2, attributes will be reloaded
# on the next access:
session.expire(obj1)
session.expire(obj2)

您可以使用session.refresh()立即获取对象的最新版本,即使会话之前已经查询过该对象。

运行此命令,强制会话从您选择的数据库更新最新值:

session.expire_all()

Excellent DOC about default behavior and lifespan of session

我只是遇到了这个问题,现有的解决方案出于某种原因对我不起作用。所做的工作是调用session.commit()。调用之后,对象从数据库中更新了值。

相关问题 更多 >