Предоставить перечисление для модели во время инициализации для преобразования атрибута - PullRequest
1 голос
/ 04 ноября 2019

Допустим, у меня есть общая модель Food sqlalchemy, которую я хочу повторно использовать в нескольких различных приложениях:

class Food(Base):
    _type = Column(Integer, index=True, unique=False, nullable=False)

Атрибут _type здесь является целым числом. Технически это может быть Enum, но я, когда пишу свою общую модель, не имею доступа к значениям enum (они определяются позже в приложениях). Я попробовал подход Mixin (см. Мой предыдущий вопрос: предоставить Enum во время создания БД ), но мой реальный вариант использования немного сложнее, чем пример Food. В этой модели определено несколько взаимосвязей, включая ту, которая указывает на модель Food. Это вынуждает меня, среди прочего, объявлять несколько отношений на уровне приложения, и я действительно не хочу этого делать.

Вместо этого я хотел бы сделать что-то вроде этого:

class FoodType(Enum):
    pass

class Food(Base):
    _type = Column(Integer, index=True, unique=False, nullable=False)

    @hybrid_property
    def type(self) -> FoodType:
        return FoodType(self._type)

    @type.setter
    def type(self, food_type):
        self._type = food_type.value

и я хотел как-то «заполнить» перечисление FoodType позже на уровне приложения, но это не представляется возможным. Я пытался переопределить / расширить / подкласс FoodType, но мои попытки не увенчались успехом.

Есть ли у вас какие-либо предложения?

1 Ответ

1 голос
/ 05 ноября 2019

Ладно, единственный способ, который я нашел, - это «подлатать обезьяну» модели / класса, передав подклассу (и расширенное) перечисление модели / классу:

class FoodType(Enum):
    pass

class Food(Base):

    food_types: FoodType

    _type = Column(Integer, index=True, unique=False, nullable=False)

    @hybrid_property
    def type(self) -> FoodType:
        return self.food_types(self._type)

    @type.expression
    def type(cls):
        return cls._type

    @type.setter
    def type(self, food_type):
        self._type = food_type.value

, а затем в моих приложениях,Я могу создать подкласс FoodType, добавить значения перечисления, и перед вызовом к create_all мне просто нужно сделать:

Food.food_types = MySubClassedEnum

...