flush 和 commit 到底差在哪?为什么没 commit 查询却看得到?批量写入应该怎么提交?这篇用第二个数据库连接当「别人」,把 flush 与 commit 的可见性和代价逐个量出来。
add 之前主键 a.id = None add 之后、flush 之前 a.id = None flush 之后 a.id = 1,发了 1 条: ['INSERT INTO author (name) VALUES (%(name)s::VARCHAR) RETURNING author.id, author.created'] 此时另一个连接查询 author 表里 f1 的行数: 0 (本会话自己查询能看到) commit 之后另一个连接查询: 1
上一篇:SQLAlchemy Identity Map;下一篇:Rollback 的实际行为。
add 之后直接查询:count = 1(查询之前先发了 INSERT: ['INSERT INTO author (name) VALU…', 'SELECT count(*) AS count_1 FRO…'] ) no_autoflush 里查询:count = 0(发了 ['SELECT'],INSERT 还没发)
flush 之后 a.created 属性是否已加载: True | flush 发了 1 条 ['INSERT'] 访问 a.created → 再发 0 条 SELECT 去取;值的类型 datetime
把 3 本书(反序)加进 session 后 flush,SQL 顺序: ['author', 'book'] 100 个 Author 一次 flush:发了 1 条 SQL(psycopg 的 insertmanyvalues 批量插入)
flush 后 rollback,库里的 gone: 0
每个对象都 flush 150.9 ms 每个对象都 commit 264.8 ms 全部 add 后一次 commit 18.6 ms
数据库在本机、fsync 关闭,逐个 commit 的真实代价在生产环境里会大得多。