python SQLModel:禁止突变

bprjcwpo  于 2022-12-10  发布在  Python
关注(0)|答案(1)|浏览(182)
from sqlmodel import SQLModel

class Foo(SQLModel):
    bar: str
        
    class Config:
        """
        Forbid mutation in order to freeze the inheriting classes
        """
        allow_mutation = False

foo = Foo(bar='bar')

生产

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_3092/4259691966.py in <module>
----> 1 foo = Foo(bar='bar')

/usr/local/lib/python3.8/site-packages/sqlmodel/main.py in __init__(__pydantic_self__, **data)
    512         object.__setattr__(__pydantic_self__, "__fields_set__", fields_set)
    513         for key, value in values.items():
--> 514             setattr(__pydantic_self__, key, value)
    515         non_pydantic_keys = data.keys() - values.keys()
    516         for key in non_pydantic_keys:

/usr/local/lib/python3.8/site-packages/sqlmodel/main.py in __setattr__(self, name, value)
    530             # non relationship values
    531             if name not in self.__sqlmodel_relationships__:
--> 532                 super().__setattr__(name, value)
    533 
    534     @classmethod

/usr/local/lib/python3.8/site-packages/pydantic/main.cpython-38-x86_64-linux-gnu.so in pydantic.main.BaseModel.__setattr__()

TypeError: "Foo" is immutable and does not support item assignment

问题:可以禁止SQLModel类的变异吗?

上下文:我有一个代码库,其中所有数据模型类都构建在冻结的Pydantic类上,我想从BaseModel迁移到SQLModel,以便存储继承的表类。
当然allow_mutation=True的工作原理就像一个魅力。

mqkwyuun

mqkwyuun1#

这可以说是SQLModel.__init__当前(0.0.8)实现中的一个bug。
它调用它自己的__setattr____setattr__又调用BaseModel.__setattr__。由于禁止突变,所以你会得到错误。这已经在这里提到过了。我还没有看到修复它的PR,所以可能需要一段时间。
同时,以下是可能的解决方法:

from sqlmodel import SQLModel

class ImmutableSQLModel(SQLModel):
    def __init__(self, **data: object) -> None:
        super().__init__(**data)
        self.__config__.allow_mutation = False

class Foo(ImmutableSQLModel):
    bar: str

if __name__ == "__main__":
    foo = Foo(bar="bar")
    print(foo)
    try:
        foo.bar = "baz"
    except Exception as e:
        print(repr(e))

输出量:

bar='bar'
TypeError('"Foo" is immutable and does not support item assignment')

相关问题