-
First Check
Commit to Help
Example Codefrom typing import NamedTuple
from uuid import UUID
from pydantic import PositiveInt
from sqlmodel import Field, SQLModel
class Coordinates(NamedTuple):
latitude: float
longitude: float
altitude: float
class Address(SQLModel, table=True):
id: UUID | None = Field(default=None, primary_key=True)
zipcode: PositiveInt
coordinates: Coordinates | None = None DescriptionHere's the error when I try creating the model with sqlmodel:
but on pydantic I used to work like this: from typing import NamedTuple
from uuid import UUID
from pydantic import BaseModel, PositiveInt
class Coordinates(NamedTuple):
latitude: float
longitude: float
altitude: float
class Address(BaseModel):
id: UUID
zipcode: PositiveInt
coordinates: Coordinates | None = None Is there any way to make this NamedTuple class work? Operating SystemLinux Operating System DetailsNo response SQLModel Version0.0.16 Python VersionPython 3.12.2 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi, had the same Question and it seems to work when you declare the column as JSON via from typing import NamedTuple
import uuid
from pydantic import PositiveInt
from sqlmodel import Field, SQLModel, create_engine, Session, select, Column, JSON
engine = create_engine(url="sqlite:///./testdb.sqlite")
class Coordinates(NamedTuple):
latitude: float
longitude: float
altitude: float
class Address(SQLModel, table=True):
id: uuid.UUID | None = Field(default_factory=uuid.uuid4, primary_key=True)
zipcode: PositiveInt
coordinates: Coordinates = Field(sa_column=Column(JSON))
SQLModel.metadata.create_all(engine)
coordinates = Coordinates(1.2, 1.3, 1.4)
coordinates_from_db = None
# Lets write an address with our NamedTuple coordinates into the DB
with Session(engine) as s:
s.add(Address(zipcode="55252", coordinates=Coordinates(1.2, 1.3, 1.4)))
s.commit()
# And now lets it read it from the DB
with Session(engine) as s:
adr = s.exec(select(Address)).first()
coordinates_from_db = adr.coordinates
# Now we compare our NamedTuple coordinates with the stuff that came from the DB
print("FROM MEM", type(coordinates), coordinates)
# > FROM MEM <class '__main__.named_tuple_as_db_col.<locals>.Coordinates'> Coordinates(latitude=1.2, longitude=1.3, altitude=1.4)
print("FROM DB", type(coordinates_from_db), coordinates_from_db)
# > FROM DB <class 'list'> [1.2, 1.3, 1.4]
print("Is it the same?", coordinates == coordinates_from_db)
# > False
print(
"is it the same if cast the result back into coordinates?",
Coordinates(*coordinates_from_db) == coordinates,
)
# > True
# Yay!
# Although the type of `coordinates_from_db` is a `list` we can use it to write coordinates into the database
with Session(engine) as s:
# This works!
s.add(Address(zipcode="55253", coordinates=coordinates_from_db))
s.commit()
|
Beta Was this translation helpful? Give feedback.
Hi, had the same Question and it seems to work when you declare the column as JSON via
Field(sa_column=Column(JSON)
...But there is one caveat; The value read from database is not a named tuple anymore but a list. One could start a conversation if that is a bug or wanted behavior or technical unavoidable behavior.. i dont know
Heres my test code, based on yours, that may help you: