由于自动刷新,Merge将仅更新数据库。您可以使用
session.no_autoflush
上下文管理器,或只是设置
autoflush=False
在您的会话中。你也可以通过
自动刷新=假
sessionmaker
需要注意的一件事是
session.query(Model).all()
因为
session
在标识图中维护唯一对象的记录(相对于主键),您将无法在同一会话中拥有同一对象的两个版本。
下面是一个示例,展示了本地更改如何与
:
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
def __repr__(self):
return "<User(name='%s')>" % self.name
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
ed_user = User(name='ed')
session.add(ed_user)
session.commit()
ed_again = session.query(User).get(1)
ed_again.name = "not ed"
with session.no_autoflush:
ed_three = session.query(User).get(1)
all_eds = session.query(User).all()
print(ed_again, id(ed_again))
print(ed_three, id(ed_three))
print(all_eds, id(all_eds[0]))
<User(name='not ed')> 139664151068624
<User(name='not ed')> 139664151068624
[<User(name='not ed')>] 139664151068624
no_autoflush
-这是意料之中的
get()
,因为它将在数据库之前首先检查身份映射,如果在身份映射中找到数据库,则不会费事查询数据库。但是有
query.all()
一场
(这也是我的直觉,但我在文档中找不到明确的解释)。
expunge
来自
一场
,但我认为获得合并对象的新旧副本的最简单方法是使用两个单独的会话,一个会话将合并并可能提交更改,另一个会话可以用于检查数据库中对象的现有状态。