如何组合SQLAlchemy的两个组件——Core(SQL表达式)和ORM? 我有一些使用ormmapper的表,而其他的只是table对象,我希望这两个表都有一个连接和一个事务。在
我有以下两个例子,但遇到了问题(结果和我交错使用两种访问样式的查询不一致)。 一个使用自动提交会话,另一个使用默认会话。在
session_autocommit=Session(bind=db,autocommit=True)
def f():
with session_autocommit.begin() as trans:
# ORM
x=session_autocommit.query(Mytable).filter(Mytable.id==1).first()
# sql expression by SQLAlchemy Core
session_autocommit.execute(mytable.update().where(mytable.c.id==1)\
.values(note=None))
# update via ORM
x.note='a'
f() # ok two update appear in log.
f() # ! only one update as below
x.note == 'a'
# the second run of f() returns False but should be True.
第二次运行f()的日志显示它只更新了一次(注=None),第二次更新丢失了吗?在
^{pr2}$更新第二个问题解决。
感谢@univerio的评论,我需要先flush
它才能正确排序执行。因为我使用了两个独立的SQLAlchemy机制。在
session=Session(bind=db,autocommit=False)
# default session must rely commit to control transaction.
session.commit()
x=session.query(Mytable).filter(Mytable.id==1).first()
x.note='a'
session.execute(mytable.update().where(mytable.c.id==1)\
.values(note=None))
session.commit()
x.note=='a'
# the test return True but should be None.
日志上说两次更新的顺序不同?在
INFO sqlalchemy.engine.base.Engine COMMIT
INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO sqlalchemy.engine.base.Engine SELECT mytable.id AS mytable_id, mytable.note AS mytable_note
FROM mytable
WHERE mytable.id = %(id_1)s
LIMIT %(param_1)s
INFO sqlalchemy.engine.base.Engine {'id_1': 1, 'param_1': 1}
INFO sqlalchemy.engine.base.Engine UPDATE mytable SET note=%(note)s WHERE mytable.id = %(id_1)s
INFO sqlalchemy.engine.base.Engine {'note': None, 'id_1': 1}
INFO sqlalchemy.engine.base.Engine SELECT mytable.id AS mytable_id
FROM mytable
WHERE mytable.id = %(param_1)s
INFO sqlalchemy.engine.base.Engine {'param_1': 1}
INFO sqlalchemy.engine.base.Engine UPDATE mytable SET note=%(note)s WHERE mytable.id = %(mytable_id)s
INFO sqlalchemy.engine.base.Engine {'note': 'a', 'mytable_id': 1}
INFO sqlalchemy.engine.base.Engine COMMIT
在阅读了更多关于
session
的文章后,我有了答案。在session
有其工作机制,一是{第一个问题是由于
unit of work
,因此SQLAlchemy将跟踪更改的内容,并且只聪明地只执行真正需要的操作。结果是只需要一次更新。第二个问题通过手动
session.flush()
ORM更新来获得正确的执行顺序来解决。因为我使用了SQLAlchemy的两个独立机制,unit of work
似乎也不适用于原始SQL表达式。相关问题 更多 >
编程相关推荐