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')
Produces
---------------------------------------------------------------------------
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
Question : Is it possible to forbid mutation for a SQLModel
class?
Context: I have a code base with all data model classes built upon frozen Pydantic classes and want to migrate from BaseModel
to SQLModel
in order to store inheriting table classes.
Of course allow_mutation=True
works like a charm.
This is arguably a bug in the current (0.0.8) implementation of SQLModel.__init__
.
It calls its own __setattr__
, which in turn calls the BaseModel.__setattr__
. Since mutation is forbidden, you get the error. This has been mentioned here already. I did not see a PR for fixing it yet, so it may take a while.
The code below is not a usable workaround . BaseModel.__config__
is a class variable, which means that with this code you effectively still set allow_mutation=False
after the first initialization. Maybe someone can come up with an idea for how to work around this issue for now.
In the meantime, here is a possible workaround:
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))
Output:
bar='bar' TypeError('"Foo" is immutable and does not support item assignment')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.