1

Let's say I have a generic Food sqlalchemy model that I want to re-use in several different apps:

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

The _type attribute here is an integer. It could technically be an Enum, but I when I write my generic model, I don't have access to the enum values (they are defined later in the apps). I tried the Mixin approach (see my previous question: provide Enum at DB creation time), but my real use case is slightly more complex than the Food example. There are multiple relationships defined on this model, including one that points back to the Food model. This forces me, among other issues, to declare several relationships at the app level and I really don't want to do that.

Instead, I would like to do something like this:

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

and I wanted to somehow "fill" the FoodType enum later at the app level, but it doesn't seem to be possible. I tried to override/extend/subclass FoodType but my attempts were unsuccessful.

Do you have any suggestion?

JPFrancoia
  • 4,866
  • 10
  • 43
  • 73

1 Answers1

1

Ok, the only way I found is to "monkey patch" the model/class by giving a subclassed (and extended) enum to the model/class:

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

and then in my apps, I can subclass FoodType, add the enum values, and before the call to create_all I just need to do:

Food.food_types = MySubClassedEnum

JPFrancoia
  • 4,866
  • 10
  • 43
  • 73