model pydantic как поле в enum

Есть класс enum:

class User_show(enum.Enum):
    error_in_db = 'error in db'
    schema_user: User

Есть модель pydantic:

class User(pydantic.BaseModel):
    pass

Есть функция:

async def show(user_id: int) -> s_return.User_show:
    async with models.async_session_factory() as session:
        try:
            query = select(models.User).filter_by(telegram_id=user_id)
            result = await session.execute(query)
        except sqlalchemy.exc.DBAPIError:
            await session.close()
            return s_return.User_show.error_in_db
    return s_return.User_show.schema_user.model_validate(result.unique().scalars().one(), from_attributes=True)

Как надо записать в enum поле User?


Ответы (1 шт):

Автор решения: insolor

Не понятно, зачем вы в enum пытаетесь дополнительно что-то воткнуть. enum вообще не для этого — он для перечисления ("enumeration") ограниченного набора возможных значений. Enum имеет смысл использовать, например, для хранения возможных ошибок, а для передачи данных — просто объект.

Можно просто создать объект с двумя полями — сообщением об ошибке (или тем самым enum, откуда выбран конкретный вид ошибки) и полем пэйлоада, что-то такого типа:

class Result(NamedTuple):
    error: str | None
    user: User | None

Если поле ошибки заполнено - значит была ошибка, если нет, значит нужно брать данные из поля user.

Можно взять готовое решение - Result из пакета returns (документация).

На вашем коде будет что-то такое (могу где-то ошибиться, потому что по вашему примеру кода нельзя точно определить, где что):

from enum import Enum
from returns.result import Result, Success, Failure


class Error(Enum):
    error_in_db = 'error in db'


async def show(user_id: int) -> Result[User, Error]:
    async with models.async_session_factory() as session:
        try:
            query = select(models.User).filter_by(telegram_id=user_id)
            result = await session.execute(query)
        except sqlalchemy.exc.DBAPIError:
            await session.close()
            return Failure(Error.error_in_db)
    return Success(User.model_validate(result.unique().scalars().one(), from_attributes=True))
→ Ссылка