TypeAdapter don't work with table=True #905
Answered
by
joachimhuet
davisylvestre
asked this question in
Questions
First Check
Commit to Help
Example Codefrom datetime import datetime
from pathlib import Path
from typing import NamedTuple
from pydantic import BeforeValidator, TypeAdapter
from sqlmodel import Field, Session, SQLModel, create_engine
from typing_extensions import Annotated
class DailyTuple(NamedTuple):
data: str
def transform_to_date(value, info):
print("Invoked")
if isinstance(value, str) and len(value) == 6:
return datetime.strptime(value, "%m%Y")
return value
MyDatetime = Annotated[datetime, BeforeValidator(transform_to_date)]
class Daily(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
data: MyDatetime
daily_adapter = TypeAdapter(list[Daily])
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url)
daily_tuple = [
DailyTuple("012023"),
DailyTuple("2023-12-15"),
DailyTuple("2018-12-18T14:29:05-03:00"),
]
daily_dict = [
{"data": "012023"},
{"data": "2023-12-15"},
{"data": "2018-12-18T14:29:05-03:00"},
]
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
def create_daily_with_model_validate(data):
with Session(engine) as session:
daily = map(Daily.model_validate, data)
session.add_all(daily)
session.commit()
def create_daily_with_type_adapter(data):
with Session(engine) as session:
daily = daily_adapter.validate_python(data)
session.add_all(daily)
session.commit()
if __name__ == "__main__":
Path(sqlite_file_name).unlink(True)
create_db_and_tables()
# OK
create_daily_with_model_validate(daily_tuple)
# OK
create_daily_with_model_validate(daily_dict)
# Invoked validate and throw sqlalchemy.orm.exc.UnmappedInstanceError
create_daily_with_type_adapter(daily_tuple)
# Did not invoke validate
create_daily_with_type_adapter(daily_dict)DescriptionTypeAdapter does not invoke validators when a model is created with the Operating SystemWindows Operating System DetailsNo response SQLModel Version0.0.16 Python VersionPython 3.12.0 Additional ContextNo response |
Answered by
joachimhuet
Apr 26, 2024
Replies: 1 comment 1 reply
|
Well it looks like TypeAdapter default validation does not take care of To make your code works I changed the following, forcing the call of daily_adapter = TypeAdapter(list[Annotated[Daily, BeforeValidator(Daily.model_validate)]]) |
1 reply
Answer selected by
davisylvestre
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Well it looks like TypeAdapter default validation does not take care of
_sa_instance_state.To make your code works I changed the following, forcing the call of
Daily.model_validateto properly instantiate an object compatible with sqlalchemy.