SQLAlchemy多对多关联插入逻辑及生成SQL语句相关问题咨询
问题1解答
SQLAlchemy是靠Session的状态跟踪和自增主键回取机制拿到这两个ID的:
- 你调用
session.add(example_batch)时,因为_allocations关系默认开启了save-update级联,关联的example_line对象也会被自动加入Session的托管队列。 - 插入带自增主键的表时,SQLAlchemy执行完INSERT语句后,会立刻调用对应数据库的自增ID获取接口(比如SQLite用
last_insert_rowid()、MySQL用2769819),把返回的自增ID赋值给对应Python对象的主键属性:batches表插入完成后example_batch的id属性就会被设为1,order_lines表插入完成后example_line的id属性会被设为1。 - Session会跟踪
example_batch和example_line的关联关系(你之前调用allocate方法把line加入了batch的_allocations集合),插入中间表allocations的时候,直接取两个对象的主键属性值拼接成插入值,就得到了(1,1)。
问题2解答
最后这条SELECT是SQLAlchemy的过期属性自动加载机制触发的:
默认配置下,调用session.commit()完成事务提交后,Session会把所有当前托管的对象的所有属性标记为「过期」,表示这些属性的值可能已经不是数据库的最新状态。后续只要有任意代码读取了example_line的任意属性(哪怕是隐式操作,比如对象序列化、调试工具读取属性),Session就会自动发起一次查询,从数据库拉取最新值填充到对象属性里,就是你看到的这条SELECT。
如果要关闭这个行为,可以在创建Session的时候加参数sessionmaker(bind=engine, expire_on_commit=False),提交后就不会自动标记属性过期,也就不会触发这条查询了。
内容的提问来源于stack exchange,提问作者hardhypochondria
相关产品推荐
相关产品推荐

