#msgspec output with SQLAlchemy model as a field

1 messages · Page 1 of 1 (latest)

zealous siren
#

Hi, i have the following msgspec model:

class ResultPriceComponent(CamelizedBaseStruct):
    component_id: UUID
    user: User

where User is a SQLAlchemy model.

I am trying to use this as a return for a route functions, but i am unable to serialize the User object, what is the recommanded way to do it ? (i get the following error)

SerializationException: Unsupported type: <class 'app.models.user.User'>

Thanks

mortal jacinth
#

Do you have the SQLAlchemy plugin installed?

zealous siren
#

Hi, yes i started with litestar-fullstack-inertia which configure the SQLAlchemy plugin

returning directly the model, with a typing User works, it's the nesting using msgspec that does not

mortal jacinth
#

Hm. It should work. Have you tried with a minimal setup?

#

Or explicitly setting return_dto?

zealous siren
#

I did try

ResultPriceComponentDTO = MsgspecDTO[ResultPriceComponent]
#

I will try to create a minimal setup

mortal jacinth
zealous siren
#

I tried with and without

mortal jacinth
#

Well it definitely can't work with!

zealous siren
#

Here is an MCVE with the same problem
This use dataclass, but i have the same problem with msgspec

Litestar version 2.21.1

from __future__ import annotations

from dataclasses import dataclass
from typing import TYPE_CHECKING

from litestar import Litestar, get
from litestar.plugins.sqlalchemy import SQLAlchemyAsyncConfig, SQLAlchemyPlugin
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

if TYPE_CHECKING:
    pass


class Base(DeclarativeBase): ...


class TodoItem(Base):
    __tablename__ = "todo_item"
    title: Mapped[str] = mapped_column(primary_key=True)
    done: Mapped[bool]


@dataclass
class Person:
    name: str
    todo: TodoItem


@get("/person/{name:str}", sync_to_thread=False)
def get_person(name: str) -> Person:
    # return Person(name=name)
    return Person(name=name, todo=TodoItem(title="test", done=True))


config = SQLAlchemyAsyncConfig(
    connection_string="sqlite+aiosqlite:///todo_async.sqlite",
    create_all=True,
    metadata=Base.metadata,
)
plugin = SQLAlchemyPlugin(config=config)
app = Litestar(route_handlers=[get_person], plugins=[plugin])

Then accessing "http://127.0.0.1:8000/person/test" create an

SerializationException on GET /person/test

Unsupported type: <class 'app.TodoItem'>
upbeat oxide
#

@zealous siren can you confirm the version of advanced alchemy you are using?

zealous siren
#

I am using version 1.9.2 during this issue, but tried 1.8.2, same issue.

#

Same on 1.7.0

zealous siren
#

Hi ! Any idea on what to do on this ?

mortal jacinth
#

Can you try this:

@dataclass
class Person[T: TodoItem]:
    name: str
    todo: T

@get("/person/{name:str}", sync_to_thread=False)
def get_person(name: str) -> Person[TodoItem]:
 ...
zealous siren
#

Hi, this seems to work, i didn't need to precise the generic on the return typing to work so:

@dataclass
class Person[T: TodoItem]:
    name: str
    todo: T

@get("/person/{name:str}", sync_to_thread=False)
def get_person(name: str) -> Person:
#

Thanks for the help, will try to work it with this