Tengo un conjunto de tablas con SQLAlchemy que se modelan como objetos que heredan del resultado a una llamada al declarative_base()
. Es decir:Sqlalchemy: evitar la herencia múltiple y tener clase base abstracta
Base = declarative_base()
class Table1(Base):
# __tablename__ & such here
class Table2(Base):
# __tablename__ & such here
etc, entonces yo quería tener algunas funciones comunes disponibles para cada una de mis clases de la tabla db, the easiest way to do this according to the docs 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 sobre esto es A) la herencia múltiple en general es un poco asquerosa (se complica al resolver cosas como llamadas super()
, etc.), B) si agrego una nueva tabla, tengo que recordar heredar tanto de Base
como de CommonRoutines
, y C) realmente eso La clase "CommonRoutines" es un tipo de tabla en cierto sentido. Realmente lo que CommonBase
es es una clase base abstracta que define un conjunto de campos & rutinas que son comunes a todas las tablas. Dicho de otra manera: "its-a" table abstract.
Por lo tanto, lo que me gustaría es la siguiente:
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 tienen que A) definir un __tablename__
para AbstractTable
, B) el aspecto de las cosas ABC causa todo tipo de dolores de cabeza, y C) tiene que indicar algún tipo de relación de DB entre AbstractTable
y cada tabla individual.
Entonces mi pregunta: ¿es posible lograr esto de una manera razonable? Lo ideal sería hacer cumplir:
- Sin herencia múltiple
CommonBase
/AbstractTable
ser abstracta (es decir, no se pueden crear instancias)
corrígeme si me equivoco, pero esas herencias "AbstractTable" debe decir "base", ¿verdad? (es decir, 'clase Table1 (Base):') –
@AdamParkin: por supuesto. corregido – van
Sí, esto era exactamente lo que estaba buscando. ¡Gracias! El único inconveniente del enfoque es que ahora el '' __init__' de la clase 'CommonBase' no se llama (' declarative_base' produce una clase que no llama 'super' en su' __init__' por lo que los mecanismos cooperativos de herencia múltiple de Python no trabajo). Hmm ... –