SQLAlchemy 的 session.query(...).all()居然会把还没 commit 的对象 flush 到数据库?
创建了一个 object, 以及把其加入到 session 里后, 查询 id 都是空, 但是执行了一次 query 之后 id 就有值了.
感觉这么处理很怪, 一个 query 语句居然会背地里对数据库做修改. 不太理解为什么要这样设计. 我觉得把修改数据库的动作放到session.add()里不是更好? query我默认就是不对数据库做修改的啊.
----------
解释一下下面的输出: User是一个类, 代表一张表, session是我创建的Session类的对象.
1. 创建一行数据(User的实例)
2. 调用session.add()加入到session
3. 查询: session.query(...).all()
------------------------
>>> user7 = User(name='test', fullname='test_full', password='nopwd')
>>> user7.id
>>> session.add(user7)
>>> user7.id
>>> session.query(User).all()
2017-01-20 16:37:00,557 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2017-01-20 16:37:00,557 INFO sqlalchemy.engine.base.Engine ('test', 'test_full', 'nopwd')
2017-01-20 16:37:00,557 INFO sqlalchemy.engine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
FROM users
2017-01-20 16:37:00,558 INFO sqlalchemy.engine.base.Engine ()
[...deleted...]
>>> user7.id
8
>>> 很多人是没 get 到我的点, 还是觉得用的人多的库, 设计上就是十全十美无可指摘?
大家觉得一个查询操作背后可以修改数据库, 这样的动作还合理的话, 可以看看这个帖子, 楼主在做类似的事情: https://www.v2ex.com/t/336226?p=1
无论如何, 执行一个 query 操作, 这个动作就应该对数据库只读, 需要刷新的话, 可以挪到其他操作中去. ----------------------- 以下是精选回复-----------------------
答:首先,并没有提交到数据库,只 flush 了, flush 和 commit 不是一件事情。其次 session 创建的时候有个 auto_flush 参数表明 query 的时候是否 flush ,默认是 True, 多看看文档,才能更好的使用
答:在 SQLAlchemy 中, add() 操作之后数据成为 pending 状态,此时数据不会立即写入到数据库中。
当你执行 query() 的时候,它会先把之前状态为 pending 的数据写入到数据库,并且更新当前 session 中存储的数据,然后再执行 query()
你可以看下文档的这个小节:
[Adding and Updating Objects]( http://docs.sqlalchemy.org/en/rel_1_1/orm/tutorial.html#adding-and-updating-objects)
答:处理是合理的,只是不太智能,对同一个对象会生成多条更新语句.性能敏感时建议直接用 sql expression
答:和 return 返回自动提交类似,也算是一种防止用户忘记 commit 的做法吧。
默认主动帮用户提交、默认不主动帮用户提交,两个方案肯定是选前者。
答:正常行为,要不然你后面需要用这个 id 怎么办
答:一般中间 query 的时候都会手动 flush,这是常识
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » SQLAlchemy 的 session.query(...).all()居然会把还没 commit 的对象 flush 到数据库?
网站模板库 » SQLAlchemy 的 session.query(...).all()居然会把还没 commit 的对象 flush 到数据库?
0条评论