Sqlalchemy: избежание множественного наследования и наличие абстрактного базового класса

Итак, у меня есть куча таблиц, использующих SQLAlchemy, которые моделируются как объекты, которые наследуются от результата вызова declarative_base(). То есть:

Base = declarative_base()
class Table1(Base):
    # __tablename__ & such here

class Table2(Base):
     # __tablename__ & such here

И т. д.Затем я хотел иметь некоторую общую функциональность, доступную для каждого из моих классов таблиц БД, самый простой способ сделать это в соответствии с документами — просто сделать множественное наследование:

Base = declarative_base()

class CommonRoutines(object):
    @classmethod
    def somecommonaction(cls):
        # body here

class Table1(CommonRoutines, Base):
    # __tablename__ & such here

class Table2(CommonRoutines, Base):
     # __tablename__ & such here

Что мне не нравится об этом: A) множественное наследование в целом немного непривычно (сложно разрешать такие вещи, как вызовы super() и т. д.), B) если я добавляю новую таблицу, я должен помнить, чтобы наследовать от обоих Base и CommonRoutines, и C) действительно, что класс "CommonRoutines" в некотором смысле "является" типом таблицы. На самом деле то, что CommonBase представляет собой абстрактный базовый класс, определяет набор полей и подпрограмм, общих для всех таблиц. Иными словами: абстрактная таблица "это-а".

Итак, я хотел бы следующее:

Base = declarative_base()

class AbstractTable(Base):
    __metaclass__ = ABCMeta  # make into abstract base class

    # define common attributes for all tables here, like maybe:
    id = Column(Integer, primary_key=True)

    @classmethod
    def somecommonaction(cls):
        # body here

class Table1(AbstractTable):
    # __tablename__ & Table1 specific fields here

class Table2(AbstractTable):
     # __tablename__ & Table2 specific fields here

Но это, конечно, не работает, так как тогда мне нужно A) определить __tablename__ для AbstractTable, B) аспект ABC вещей вызывает всевозможные головные боли, и C) должен указать какую-то связь DB между AbstractTable и каждой отдельной таблицей.

Итак, мой вопрос: возможно ли добиться этого разумным способом? В идеале я хотел бы обеспечить:

  • Нет множественного наследования
  • CommonBase/AbstractTable быть абстрактным (т.е. нельзя создать экземпляр)

16
задан Milorad Pop-Tosic 25 June 2014 в 00:46
поделиться