Так, например, у меня есть два класса:
Base = declarative_base()
class Vendor(Base):
__tablename__ = "vendor"
id = Column(Integer, primary_key=True)
name = Column(String(45))
def __init__(self, name):
self.name = name
def __repr__(self):
return "<Vendor id=%d>" % self.id
class Site(Base):
__tablename__ = "site"
id = Column(Integer, primary_key=True)
vendor_id = Column(Integer, ForeignKey('vendor.id'))
vendor = relation(Vendor)
def __init__(self, name, code, location):
self.name = name
def __repr__(self):
return "<Site id=%d>" % self.id
class SQLSchema:
def __init__(self):
self.engine = create_engine('...', echo=False)
self.metadata = Base.metadata
self.session = sessionmaker(bind=self.engine)()
self.create()
def create(self):
self.metadata.create_all(self.engine)
Я упростил структуру классов, теперь, используя эти классы, я могу использовать:
sql = sqlschema.SQLSchema()
Так что иногда мне нужен легкий доступ к Продавцу, что означает, что я могу использовать:
v = sql.session.query(self).filter_by(name='test').one()
Я бы предпочел упростить доступ, используя родственные (в настоящее время мои лучшие усилия):
Vendor.get(sql.session, name='A-01')
Меня поразило, что функция get
является довольно общей, что я хотел бы, чтобы все мои классы наследовали от Base, и я искал лучший способ сделать это. Есть два способа, которыми я могу думать:
- Микс-класс
- Изменение метакласса, предоставленного в Declarative_base
Пример модификации метакласса
class MyDeclarativeMeta(DeclarativeMeta):
def get(self, session, **filterargs):
session.query(self).filter_by(**filterargs).one()
## ...
Base = declarative_base(metaclass=MyDeclarativeMeta)
Я бы хотел создать что-нибудь с наименьшим возможным сюрпризом. Каково мнение людей по поводу вариантов, которые я представил, и есть ли лучший путь в целом?