关于在 sqlalchemy 会话中刷新对象
好吧,我正在处理有关 sqlalchemy 和对象刷新的疑问!
Well, I am dealing with a doubt about sqlalchemy and objects refreshing!
我的情况是我有 2 个会话,并且在两个会话中都查询了同一个对象!...对于某些特定的事情,我无法关闭其中一个会话.我已经修改了对象并在会话 A 中提交了更改,但是在会话 B 中,属性是初始的!无需修改!...
I am in the situation in what I have 2 sessions, and the same object has been queried in both sessions!... For some particular thing I cannot to close one of the sessions. I have modified the object and commited the changes in session A, but in session B, the attributes are the initial ones! without modifications!..
那么...我应该实现某种通知系统来传达更改还是在 sqlalchemy 中有一种内置的方法可以做到这一点??
So... shall I implement some kind of notification system to communicate changes or there is a built-in way to do this in sqlalchemy??
推荐答案
会话被设计成这样工作.会话 B 中对象的属性将保留它在会话 B 中第一次查询时的属性.此外,当其他会话中的对象发生变化时,SQLAlchemy 不会尝试自动刷新它们,我也不认为尝试创建某些东西是明智的像这样.
Sessions are designed to work like this. The attributes of the object in Session B WILL keep what it had when first queried in Session B. Additionally, SQLAlchemy will not attempt to automatically refresh objects in other sessions when they change, nor do I think it would be wise to try to create something like this.
您应该积极地将每个会话的生命周期视为数据库中的单个事务.会话需要如何以及何时处理它们的对象可能陈旧的事实并不是一个技术问题,可以通过内置于 SQLAlchemy(或 SQLAlchemy 的任何扩展)中的算法解决:这是一个业务"问题,您必须使用它的解决方案自己确定和编码.正确"的回应可能是说这不是问题:如果会话 B 使用了会话 B 启动时的数据,则发生在会话 B 上的逻辑可能是有效的.您的问题"实际上可能不是问题.文档实际上有一个 关于何时使用会话的整个部分,但如果您希望有一个统一的尺寸,它会给出非常严峻的回应-所有解决方案...
You should be actively thinking of the lifespan of each session as a single transaction in the database. How and when sessions need to deal with the fact that their objects might be stale is not a technical problem that can be solved by an algorithm built into SQLAlchemy (or any extension for SQLAlchemy): it is a "business" problem whose solution you must determine and code yourself. The "correct" response might be to say that this isn't a problem: the logic that occurs with Session B could be valid if it used the data at the time that Session B started. Your "problem" might not actually be a problem. The docs actually have an entire section on when to use sessions, but it gives a pretty grim response if you are hoping for a one-size-fits-all solution...
会话通常在逻辑的开头构建可能需要访问数据库的操作.
A Session is typically constructed at the beginning of a logical operation where database access is potentially anticipated.
Session,每当它被用来与数据库交谈时,就会开始一个数据库事务一开始通信.假设自动提交标志保留其推荐的默认值 False,这事务一直在进行,直到会话回滚,提交,或关闭.Session 将开始一个新的事务,如果它在前一个交易结束后再次使用;从这表明 Session 能够有一个生命周期跨越许多事务,尽管一次只有一个.我们参考这些事务作用域和会话作用域两个概念.
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.
这里的含义是 SQLAlchemy ORM 鼓励开发人员在他或她的应用程序中建立这两个范围,不仅包括范围何时开始和结束,还包括范围在这些范围中,例如单个 Session 实例应该是本地的到函数或方法内的执行流程,它应该是整个应用程序使用的全局对象,或介于两者之间这两个.
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.
确定此范围的开发人员的负担是一个方面SQLAlchemy ORM 必须对如何应该使用数据库.工作单元模式具体是随着时间的推移积累变化并定期刷新它们之一,保持内存状态与已知存在于本地交易.这种模式只有在有意义时才有效交易范围已到位.
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.
也就是说,您可以采取一些措施来改变这种情况的运作方式:
That said, there are a few things you can do to change how the situation works:
首先,您可以缩短会话保持打开状态的时间.会话 B 正在查询该对象,然后您正在对该对象(在同一会话中)执行某些操作,以便使属性保持最新.一种解决方案是在单独的会话中完成第二个操作.
First, you can reduce how long your session stays open. Session B is querying the object, then later you are doing something with that object (in the same session) that you want to have the attributes be up to date. One solution is to have this second operation done in a separate session.
另一个是使用 expire/refresh 方法,如 文档显示...
Another is to use the expire/refresh methods, as the 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()
立即获取对象的最新版本,即使会话之前已经查询过该对象.
You can use session.refresh()
to immediately get an up-to-date version of the object, even if the session already queried the object earlier.
相关文章