Quindi ho un mucchio di tabelle che usano SQLAlchemy che sono modellate come oggetti che ereditano dal risultato in una chiamata a declarative_base()
. Vale a dire:Sqlalchemy: evitare l'ereditarietà multipla e avere una classe di base astratta
Base = declarative_base()
class Table1(Base):
# __tablename__ & such here
class Table2(Base):
# __tablename__ & such here
ecc Poi volevo avere alcune funzionalità comuni a disposizione di ciascuna delle mie classi della tabella DB, the easiest way to do this according to the docs è quello di fare proprio l'ereditarietà multipla:
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
La cosa non mi piace A proposito di questo è A) ereditarietà multipla in generale è un po 'icky (diventa difficile risolvere le cose come super()
chiamate, ecc), B) se aggiungo una nuova tabella che devo ricordare di ereditare da entrambi Base
e CommonRoutines
e C) davvero quello "CommonRoutines" classe "is-a" tipo di tabella in un certo senso. In realtà ciò che è CommonBase
è una classe base astratta che definisce un insieme di routine di campi & comuni a tutte le tabelle. Detto in altro modo: "è un tavolo astratto".
Quindi, quello che vorrei è questa:
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
Ma questo, naturalmente, non funziona, come ho poi devo A) definire un __tablename__
per AbstractTable
, B) l'aspetto delle cose ABC causa tutti i tipi di mal di testa, e C) devono indicare una sorta di relazione DB tra AbstractTable
e ogni singola tabella.
Quindi la mia domanda: è possibile raggiungere questo in un modo ragionevole? Idealmente mi piacerebbe far rispettare:
- No ereditarietà multipla
CommonBase
/AbstractTable
essere astratto (cioè non è possibile creare un'istanza)
correggetemi se sbaglio, ma quelle eredità "AbstractTable" dovrebbe leggere "Base", giusto? (es. 'class Table1 (Base):') –
@AdamParkin: ovviamente. corretto. – van
Sì, questo era esattamente quello che stavo cercando. Grazie! L'unico svantaggio di questo approccio è che ora non viene chiamato il '' Bite_base' della classe 'CommonBase'' '___init__' '(' declarative_base' produce una classe che non chiama' super' nel suo '__init__' così i meccanismi multipli di ereditarietà cooperativa di Python non lavoro). Hmm .... –