Tak więc mam kilka tabel przy użyciu SQLAlchemy, które są modelowane jako obiekty, które dziedziczą od wyniku do połączenia z declarative_base()
. Tj:Sqlalchemy: unikanie dziedziczenia wielokrotnego i posiadanie abstrakcyjnej klasy bazowej
Base = declarative_base()
class Table1(Base):
# __tablename__ & such here
class Table2(Base):
# __tablename__ & such here
Itd Potem chciał mieć jakąś wspólną funkcjonalność dostępną dla każdego z moich klas tabeli DB, the easiest way to do this according to the docs jest po prostu zrobić wielokrotne dziedziczenie:
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
Rzecz Nie lubię o tym jest A) wiele dziedziczenia w ogóle jest trochę nieprzyjemne (dostaje trudne rozwiązania takie jak wywołania super()
, itp.), B) jeśli dodaję nową tabelę muszę pamiętać, aby dziedziczyć po obu Base
i CommonRoutines
i C) naprawdę to "CommonRoutines" klasa "is-a" rodzaj tabeli w pewnym sensie. Naprawdę to, co jest CommonBase
jest abstrakcyjną klasą bazową, która definiuje zestaw procedur, które są wspólne dla wszystkich tabel. Innymi słowy: "jego-a" abstrakcyjny stół.
Więc, co chciałbym to:
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
Ale to oczywiście nie działa, bo wtedy trzeba A) zdefiniować __tablename__
dla AbstractTable
b) aspekt ABC rzeczy powoduje różnego rodzaju bóle głowy, a C) musi wskazywać na pewien rodzaj związku DB między AbstractTable
a każdą poszczególną tabelą.
Moje pytanie: czy możliwe jest osiągnięcie tego w rozsądny sposób? Idealnie chciałbym wymusić:
- Nie wielokrotne dziedziczenie
CommonBase
/AbstractTable
być abstrakcyjne (czyli nie może być instancja)
Popraw mnie jeśli się mylę, ale te „AbstractTable” spadki powinien przeczytać „baza”, prawda? (tzn. 'klasa Table1 (Base):') –
@AdamParkin: oczywiście. poprawione. – van
Yup, to było dokładnie to, czego szukałem. Dzięki! Jedyną wadą tego podejścia jest to, że teraz klasa '__init__' klasy" CommonBase "nie jest wywoływana (' deklarative_base' tworzy klasę, która nie wywołuje 'super' w jej' __init__', więc Python współpracujące mechanizmy dziedziczenia wielu nie praca). Hmm .... –