Search code examples
pythonsqlalchemymixins

Is there a way to include the same Mixin more than once in a subclass in Python?


Normally a Python mixin would only be included once, like:

class MyMixin:
    pass
class Child(Base, MyMixin):
    pass

However, in some situation it would be handy if we can use the same Mixin twice. For example, I have a Mixin in SQLAlchemy defining some Columns as follow:

class MyNoteMixin:
    note = Column(String)
    by_who = Column(String)

Now I have a subclass that inherits from the above Mixin, but needs two different columns both are of a note nature. Can I do something like:

class Child(Base, MyNoteMixin as "Description", MyNoteMixin as "Quote"):
        pass

So that the resolved table would contain a column named Description that is exactly a MyNoteMixin copy except for the name, AND also has another column named Quote with the same nature.

Is this possible with SQLAlchemy? Or generally speaking, is such usage of Mixin even possible in Python? Thanks.


Solution

  • I would recommend using python decorator.

    Here is an example how to get this using plan python class:

    def custom_fields(**kwargs):
        def wrap(original_class):
            """
            Apply here your logic, could be anything!
            """
            for key, val in kwargs.items():
                setattr(original_class, key, val)
            return original_class
        return wrap
    
    
    @custom_fields(quote='String here, can be SQLAlchemy column object')
    class Child:
        pass
    
    
    print(Child.quote)
    

    Output:

    >>> String here, can be SQLAlchemy column object
    

    You will have to adapt it for sqlalchemy, like connect the setattr to your MyNoteMixin.