Итак, у меня есть куча таблиц, использующих 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
быть абстрактным (т.е. нельзя создать экземпляр)