Open
Description
First Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn't find it.
- I searched the SQLModel documentation, with the integrated search.
- I already searched in Google "How to X in SQLModel" and didn't find any information.
- I already read and followed all the tutorial in the docs and didn't find an answer.
- I already checked if it is not related to SQLModel but to Pydantic.
- I already checked if it is not related to SQLModel but to SQLAlchemy.
Commit to Help
- I commit to help with one of those options 👆
Example Code
from typing import Optional
from pydantic import BaseModel, PrivateAttr
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
_name: str = PrivateAttr(default=None) # This field is not committed to the db
secret_name: str
class HeroPydantic(BaseModel):
_name: str = PrivateAttr(default=None)
secret_name: str
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True)
if __name__ == "__main__":
SQLModel.metadata.create_all(engine)
hero_1 = Hero(secret_name="Dive Wilson")
print("Hero:", hero_1)
print(hero_1._name)
print(hero_1._name is None, type(hero_1._name))
hero_2 = HeroPydantic(secret_name="Lance")
print(hero_2)
print(hero_2._name)
print(hero_2._name is None, type(hero_2._name))
with Session(engine) as session:
session.add(hero_1)
session.commit()
statement = select(Hero)
results = session.exec(statement)
for hero in results:
print(hero)
print(hero_2._name)
print(hero_2._name is None, type(hero_2._name))
Description
As far as I can tell SQLModel is ignoring the default
and default_factory
parameters of pydantic.PrivateAttr
. The example I've given above reproduces on my system. The output can be seen here:
Hero: id=None secret_name='Dive Wilson'
False <class 'pydantic.fields.ModelPrivateAttr'>
secret_name='Lance'
None
True <class 'NoneType'>
2021-10-28 12:17:30,129 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2021-10-28 12:17:30,131 INFO sqlalchemy.engine.Engine INSERT INTO hero (secret_name) VALUES (?)
2021-10-28 12:17:30,131 INFO sqlalchemy.engine.Engine [generated in 0.00015s] ('Dive Wilson',)
2021-10-28 12:17:30,131 INFO sqlalchemy.engine.Engine COMMIT
2021-10-28 12:17:30,143 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2021-10-28 12:17:30,144 INFO sqlalchemy.engine.Engine SELECT hero.id, hero.secret_name
FROM hero
2021-10-28 12:17:30,144 INFO sqlalchemy.engine.Engine [no key 0.00010s] ()
secret_name='Dive Wilson' id=1
False <class 'pydantic.fields.ModelPrivateAttr'>
2021-10-28 12:17:30,144 INFO sqlalchemy.engine.Engine ROLLBACK
As you can see the field is not set to None
, and instead is an empty instance of pydantic.fields.ModelPrivateAttr
.
Operating System
macOS
Operating System Details
No response
SQLModel Version
0.0.4
Python Version
3.9.5
Additional Context
No response