能否为SQLModel类禁止修改(mutation)?Pydantic迁移场景咨询
为SQLModel类实现禁止修改(Immutable)的方案
问题背景
原有代码库基于冻结(frozen)的Pydantic BaseModel构建数据模型,迁移至SQLModel以支持继承表类时,尝试通过allow_mutation=False配置禁止实例修改,却在实例化阶段触发TypeError,提示类不可变不支持赋值。已知allow_mutation=True可正常运行,需实现SQLModel类的不可变特性。
问题原因
SQLModel的__init__方法内部通过setattr为实例赋值字段,而allow_mutation=False(或Pydantic V2的frozen=True)会拦截所有setattr操作,包括初始化阶段的字段赋值,导致实例化失败。
解决方案
重写SQLModel的__init__方法,使用object.__setattr__绕过冻结限制完成初始化赋值,之后保持实例不可变。推荐使用Pydantic V2标准配置frozen=True替代allow_mutation=False。
代码示例
from sqlmodel import SQLModel class Foo(SQLModel): bar: str class Config: frozen = True # Pydantic V2标准冻结配置,替代allow_mutation=False def __init__(self, **data): # 先完成数据验证 validated_instance = self.model_validate(data) # 用object.__setattr__直接赋值,绕过冻结限制 for key, value in validated_instance.model_dump().items(): object.__setattr__(self, key, value) # 同步设置已赋值字段集合 object.__setattr__(self, "__fields_set__", validated_instance.__fields_set__) # 正常实例化 foo = Foo(bar='bar') print(foo.bar) # 输出: bar # 尝试修改会触发报错,符合冻结要求 # foo.bar = 'new_value' # 执行会抛出 TypeError: "Foo" is immutable and does not support item assignment
验证效果
- 实例化过程正常完成,字段值正确初始化
- 后续尝试修改实例字段会触发
TypeError,保证实例不可变 - 完全兼容SQLModel的数据库操作特性(如继承表类的存储)
内容的提问来源于stack exchange,提问作者solknar
相关产品推荐
相关产品推荐

