Sqlalchemy: evitar la herencia múltiple y tener una clase base abstracta
Así que tengo un montón de tablas usando SQLAlchemy que se modelan como objetos que heredan del resultado a una llamada adeclarative_base()
. Es decir
Base = declarative_base()
class Table1(Base):
# __tablename__ & such here
class Table2(Base):
# __tablename__ & such here
Etc. Entonces quería tener alguna funcionalidad común disponible para cada una de mis clases de tabla de base de datos, la forma más fácil de hacer esto de acuerdo con los documentos es simplemente hacer herencia múltiple:
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
Lo que no me gusta de esto es A) la herencia múltiple en general es un poco asquerosa (se vuelve difícil resolver cosas comosuper()
llamadas, etc.), B) si agrego una nueva tabla, debo recordar heredar de ambasBase
yCommonRoutines
, y C) realmente esa clase "CommonRoutines" es "un" tipo de tabla en cierto sentido. Enserio queCommonBase
es una clase base abstracta que define un conjunto de campos y rutinas que son comunes a todas las tablas. Dicho de otra forma: tabla abstracta "its-a".
Entonces, lo que me gustaría es esto:
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
Pero esto, por supuesto, no funciona, ya que luego tengo que A) definir un__tablename__
paraAbstractTable
, B) el aspecto ABC de las cosas causa todo tipo de dolores de cabeza, y C) tiene que indicar algún tipo de relación DB entreAbstractTable
y cada tabla individual.
Entonces mi pregunta: ¿es posible lograr esto de una manera razonable? Idealmente me gustaría hacer cumplir:
Sin herencia múltipleCommonBase
/AbstractTable
ser abstracto (es decir, no puede ser instanciado)