SQLAlchemy==1.2.18
result = db.session.query(ObjectModel).get(ids.get("id"))
result.status = 2 #此時 session._is_clean() = False
#中間執行一次yield遠程調用
#外部請求函數
def onAyncFetch():
req = ...省略其它代碼
response = yield async_http.fetch(req)
...省略其它代碼
return Return(json_decode(response.body))
print id(result.query.session)
data = yield onAyncFetch(...)
print id(result.query.session) #兩次打印內存地址不相同
...省略其它代碼
#執行yield調用結束之後 session._is_clean() = True
db.session.commit() #再進行commit的會進行如下代碼段,上面修改的status字段無法被commit
上面是一段僞代碼.流程大概就這樣,下面貼sqlalchemy時commiit的源碼
sqlalchemy/orm/session.py
def _prepare_impl(self):
self._assert_active()
if self._parent is None or self.nested:
self.session.dispatch.before_commit(self.session)
stx = self.session.transaction
if stx is not self:
for subtransaction in stx._iterate_self_and_parents(upto=self):
subtransaction.commit()
if not self.session._flushing:
for _flush_guard in range(100):
if self.session._is_clean(): # 判斷對象信息是否變更,如果變更則執行flush()
break
self.session.flush()
else:
raise exc.FlushError(
"Over 100 subsequent flushes have occurred within "
"session.commit() - is an after_flush() hook "
"creating new objects?"
)
if self._parent is None and self.session.twophase:
try:
for t in set(self._connections.values()):
t[1].prepare()
except:
with util.safe_reraise():
self.rollback()
self._state = PREPARED