SQLAlchemy中Session如何跟踪对象变更?InstanceState与Mapper作用机制问询
SQLAlchemy 核心组件原理答疑
1. InstanceState 核心概念
每个经过ORM插桩的映射类实例,都会内置一个_sa_instance_state属性,这就是InstanceState的实例。它是业务实例和ORM底层系统之间的隔离代理层,存储了实例的所有持久化相关元数据:包括实例当前的生命周期状态(临时/待持久化/持久化/游离)、属性的原始值快照、已变更属性列表、关联的Session引用、对应的Mapper引用等。
2. InstanceState 与 Session 的关联及变更跟踪逻辑
当映射类实例被调用session.add()方法加入会话时,InstanceState会首先完成和当前Session的绑定,同时Session会将该实例存入自身的identity map做生命周期管理。
关于变更跟踪的实现逻辑:
- 属性变更触发时,基于描述符实现的插桩逻辑会首先拦截赋值操作,将新值和
InstanceState中存储的原始快照做对比,如果确认发生变更,会在InstanceState中标记修改的属性、存储最新值,同时会主动将当前实例加入所属Session的dirty集合,不需要Session遍历所有对象才能发现变更。 Session执行flush操作刷入数据库时,优先处理dirty集合中的实例,逐个读取对应InstanceState中记录的变更内容生成SQL。仅会在做一致性校验时遍历identity map中的对象,避免出现绕过描述符赋值导致的漏更问题。- 最终执行的数据库变更操作,完全以
InstanceState中记录的变更为准,执行前会做冲突校验(如乐观锁校验、外键关联校验等),校验通过后才会实际执行。
3. Mapper 的介入时机与角色
Mapper负责存储映射类属性和数据表列的对应关系、关联关系配置、字段校验规则等元信息,它的介入主要分两个阶段:
- 属性变更阶段:描述符拦截到属性赋值操作后,会首先调用对应
Mapper中该属性的配置规则,完成类型校验、关联关系逻辑处理(如外键关联的反向赋值),校验通过后才会更新InstanceState中的变更记录,符合观察者模式的类比定义:
可以将插桩理解为在观察者模式中,透明地为被映射类添加「被观察者」实现,而
Mapper就是对应的「观察者」。
- SQL生成阶段:
Session执行flush生成SQL时,会调用Mapper将InstanceState中记录的属性变更,转换为对应的数据表列名、SQL参数,最终生成可执行的INSERT/UPDATE/DELETE语句。InstanceState本身不会直接调用Mapper,所有对Mapper的调用都由插桩描述符、Session两个模块触发。
内容的提问来源于stack exchange,提问作者Shahar
相关产品推荐
相关产品推荐

