✨ Ensure that type checks are executed when setting `table=True`
I found that when table=True is set, pydantic becomes invalid for usage like hero = Hero(name="Deadpond", secret_name="Dive Wilson", age="test"). As the document says you get all of Pydantic's features, including automatic data validation, serialization, and documentation. You can use SQLModel in the same way you can use Pydantic., I think table=True makes pydantic invalid is a bug, so I tried to fix it.
I delete a test case because this case is incompatible with pydantic. I also add a test case to ensure my code works. For current code, my new test case would fail, but it would pass for my new code.
Some related issues for this one:
- Some discussion on how to run validations in sqlmodel
- Seems like pydantic validations are intended to be supported in sqlmodel
However, I think this comment indicates that this is actually the desired behavior.
this is actually the desired behavior
I regard this action as a bug rather than a feature because sqlmodel announce that you get all of Pydantic's features, including automatic data validation, serialization, and documentation. You can use SQLModel in the same way you can use Pydantic. Models with no validation when table=True is definitely not the way we are using pydantic.
Hi all, is there a plan to merge this? Currently facing the same issues discussed in #11 and #453 (and several other related issues) and none of the proposed workaround seem clean enough for my use case.
Thanks.
@tiangolo Would you please look at this PR snd see whether this solution is OK? It passes all tests.
Hey, bumping this because we urgently need it as well :)
Thanks!
@ohadc-orchid
Fortunately, there seems to be an easy solution.
class Config:
validate_assignment = True
from datetime import datetime
from pydantic import BaseModel
from sqlmodel import SQLModel, Field
class DatetimeModel(BaseModel):
timestamp: datetime
class DatetimeSQLModel(SQLModel):
id: str = Field("dummy", primary_key=True)
timestamp: datetime
class DatetimeSQLTableModel(SQLModel, table=True):
id: str = Field("dummy", primary_key=True)
timestamp: datetime
class Config:
validate_assignment = True
t = '2024-11-13T12:30:12.584245Z'
m1 = DatetimeModel(timestamp=t)
m2 = DatetimeSQLModel(timestamp=t)
m3 = DatetimeSQLTableModel(timestamp=t)
print(type(m1.timestamp))
print(type(m2.timestamp))
print(type(m3.timestamp))
if __name__ == '__main__':
pass
Bumping this. I get @tiangolo 's intention, but it seems that things are naturally leaning in another direction. If nothing is wrong with this implementation, then I think it's a huge step forward.
@ohadc-orchid
Fortunately, there seems to be an easy solution.
class Config: validate_assignment = Truefrom datetime import datetime from pydantic import BaseModel from sqlmodel import SQLModel, Field class DatetimeModel(BaseModel): timestamp: datetime class DatetimeSQLModel(SQLModel): id: str = Field("dummy", primary_key=True) timestamp: datetime class DatetimeSQLTableModel(SQLModel, table=True): id: str = Field("dummy", primary_key=True) timestamp: datetime class Config: validate_assignment = True t = '2024-11-13T12:30:12.584245Z' m1 = DatetimeModel(timestamp=t) m2 = DatetimeSQLModel(timestamp=t) m3 = DatetimeSQLTableModel(timestamp=t) print(type(m1.timestamp)) print(type(m2.timestamp)) print(type(m3.timestamp)) if __name__ == '__main__': pass
This works for type validations(as PR aims to fix) but it is not very helpful if you want to use field validators, please see the comment: https://github.com/fastapi/sqlmodel/issues/52#issuecomment-2372511953
Just wanted to point it out if someone ends up here looking for how to work with field or model validators like me.
this is actually the desired behavior
I regard this action as a bug rather than a feature because
sqlmodelannounce that you get all of Pydantic's features, including automatic data validation, serialization, and documentation. You can use SQLModel in the same way you can use Pydantic. Models with no validation whentable=Trueis definitely not the way we are using pydantic.
Agree with this interpretation, but at the same time the code seems to explicitly try to avoid that behaviour (https://github.com/fastapi/sqlmodel/blob/main/sqlmodel/_compat.py#L564). Would love some clarity from the FastAPI folks on the intention here. This was definitely the most surprising behaviour I noticed using SQLModel.
Hi all!
The current behaviour is clearly intentional, as stated in the docs and the code, and as further explained by Tiangolo here.
As such, I think it's unlikely that Tiangolo will want to change this behaviour. Nevertheless, I'll request his feedback internally.
Personally I think that if we choose to keep the current behaviour, we should consider adding more detailed documentation (and examples) about this functionality, as it's clearly unintuitive for many users.