在初始化时提供一个枚举进行建模以进行属性转换

时间:2019-11-04 13:12:39

标签: python enums sqlalchemy

假设我有一个通用的Food sqlalchemy模型,希望在多个不同的应用程序中重复使用:

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

此处的_type属性是一个整数。从技术上讲,它可以是枚举,但是当我编写通用模型时,我无法访问枚举值(它们将在稍后的应用程序中定义)。我尝试了Mixin方法(请参阅上一个问题:provide Enum at DB creation time),但是我的实际用例比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 个答案:

答案 0 :(得分:1)

好吧,我发现的唯一方法是通过给模型/类一个子类化(和扩展的)枚举来“猴子补丁”模型/类:

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