Different behaviour between pydantic and SQLModel when serializing and deserializing a datetime field with schema_extra #1587
-
First Check
Commit to Help
Example Codefrom datetime import datetime
from pydantic import Field as PdField, BaseModel
from sqlmodel import Field as SmField, SQLModel
def test_sqlmodel_json_serialization_and_deserialization_of_datetime():
# Create a model class locally to avoid pytest collection issues
class TestModel(SQLModel):
timestamp: datetime = SmField(schema_extra={"validation_alias": "test"})
# Create a model instance with a datetime
original_datetime = datetime(2023, 1, 1, 12, 0, 0)
model = TestModel(timestamp=original_datetime)
# Serialize to JSON
json_str = model.model_dump_json()
# Deserialize from JSON
deserialized_model = TestModel.model_validate_json(json_str)
# Check that the datetime is preserved correctly
assert isinstance(deserialized_model.timestamp, datetime)
assert deserialized_model.timestamp == original_datetime
def test_pydantic_json_serialization_and_deserialization_of_datetime():
# Create a model class locally to avoid pytest collection issues
class TestModel(BaseModel):
timestamp: datetime = PdField(strict=True)
# Create a model instance with a datetime
original_datetime = datetime(2023, 1, 1, 12, 0, 0)
model = TestModel(timestamp=original_datetime)
# Serialize to JSON
json_str = model.model_dump_json()
# Deserialize from JSON
deserialized_model = TestModel.model_validate_json(json_str)
# Check that the datetime is preserved correctly
assert isinstance(deserialized_model.timestamp, datetime)
assert deserialized_model.timestamp == original_datetime
def test_sqlmodel_json_serialization_and_deserialization_of_datetime_with_empty_schema_extras():
# Create a model class locally to avoid pytest collection issues
class TestModel(SQLModel):
timestamp: datetime = SmField(schema_extra={})
# Create a model instance with a datetime
original_datetime = datetime(2023, 1, 1, 12, 0, 0)
model = TestModel(timestamp=original_datetime)
# Serialize to JSON
json_str = model.model_dump_json()
# Deserialize from JSON
deserialized_model = TestModel.model_validate_json(json_str)
# Check that the datetime is preserved correctly
assert isinstance(deserialized_model.timestamp, datetime)
assert deserialized_model.timestamp == original_datetime DescriptionI create a simple model with a strict datetime field. When I serialize the model to json and deserialize it back I expect SQLModel to behave the same as the BaseModel in pydantic, but the SQLModel test raises an exception:
After trying around some scenarios I found that setting any Operating SystemLinux Operating System DetailsNo response SQLModel Version0.0.25 Python VersionPython 3.13.7 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
The issue occurs because when you use SolutionDon't use from datetime import datetime
from sqlmodel import Field, SQLModel
from pydantic import field_validator
class TestModel(SQLModel):
timestamp: datetime = Field()
@field_validator('timestamp', mode='before')
@classmethod
def validate_timestamp(cls, v):
if isinstance(v, str):
return datetime.fromisoformat(v)
if isinstance(v, datetime):
return v
raise ValueError('timestamp must be a datetime or ISO format string') Or simply use the field without class TestModel(SQLModel):
timestamp: datetime = Field() Why This Happens
RecommendationAvoid using |
Beta Was this translation helpful? Give feedback.
-
This is only related to In your first code example you use
(missing value for required field That's because you specified I'll close this as a duplicate of #816. Let's track this there |
Beta Was this translation helpful? Give feedback.
This is only related to
schema_extra={"strict": True}
.It has already been reported here: #816
In your first code example you use
schema_extra={"validation_alias": "test"}
and in this case everything works as expected.You have
(missing value for required field
test
)That's because you specified
validation_alias
and now Pydantic expects to find value fortimestamp
field…