tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.62k stars 383 forks source link

Support real enums #937

Open numberZero opened 3 years ago

numberZero commented 3 years ago

Both MySQL and PostgreSQL support real type-safe enums, while TortoiseORM only provides some sugar to access a numerical or text field as if it was enum.

sasha-id commented 2 years ago

+1

Chr0nos commented 2 months ago

https://www.postgresql.org/docs/current/datatype-enum.html

i've tried to implement it on my own but i'm facing 2 issues: 1: i was not able to find documentation on aerich to learn where the migration part of an implemented "Field" is made so i cannot implement my own, as a workaround i've just changed the migration manualy to create the field 2: pydantic_model_creator don't like it and throw a pydantic.errors.PydanticUserError: Field 'seniority' requires a type annotation error to me

the code that i've used:

from enum import Enum
from typing import Type

from tortoise.fields import Field

def enum_type_factory(name: str, enum: Enum) -> Type[Field]:
    # https://www.postgresql.org/docs/current/datatype-enum.html
    class EnumField(Field):
        SQL_TYPE = name

        @classmethod
        def to_db_value(cls, value, instance) -> str:
            if isinstance(value, Enum):
                return value.value
            return value

        @classmethod
        def to_python_value(cls, value):
            if isinstance(value, Enum):
                return value
            return enum(value)

        def describe(self, serializable=False):
            description = super().describe(serializable)
            description.update({"enum": [item.value for item in enum]})
            return description

    return EnumField

it was able to interact with the models but not to use pydantic_model_creator