SQLAlchemy 里同一行数据会不会变成两个对象?session.get 什么时候不发 SQL?为什么另一个会话改了数据我这里却看不到?这篇用 SQLite 与两个 session 把身份映射的行为逐个量出来。
用两种不同的条件查同一行:a is b → True(第二次仍然发了 1 条 SQL,但返回的是已有对象) 不同的 session 里查同一行 → 不同对象: True identity key: (<class '__main__.User'>, (1,), None)
上一篇:N+1 查询问题;下一篇:Session Flush 与 Commit。
已经加载过的主键:get 发了 0 条 SQL,x is a → True 没加载过的主键:get 发了 1 条 SQL 再 get 一次:0 条 不存在的主键 999:1 条 SQL,返回 None;再 get 一次 999: 1 条(不存在的结果不缓存)
加载 5 个对象后 identity_map 大小: 5 del 掉列表并 gc 之后: 0 改了一个对象再丢掉引用并 gc: 1 (被修改的对象 session 持有强引用,直到 flush)
session A 读到 score = 0 另一个 session 把 score 改成 99 并提交之后,session A 重新查询:a2.score = 0 (a2 is a → True ) populate_existing=True 重新查询:score = 99 session.refresh(a) 之后:score = 100 session.expire(a) 之后下一次读取:score = 101
IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: user.id
两个请求里 get 到的是不是同一个对象: False 同一个请求里连续 get 两次,但不保留返回值:共发 2 条 SQL(第一次的对象没人引用,被回收了,第二次只好重新查) 保留第一次的返回值再 get:共发 1 条 SQL