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_datetimeDescriptionI 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_aliasand now Pydantic expects to find value fortimestampfield…