比如说,我有两个类(class):
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)
我想创造一些尽可能不令人惊讶的东西。人们对我提出的选项有何看法?是否有更好的方法?
最佳答案
对于简单用例,声明式不需要自定义元类,对于困难用例也几乎不需要。 Mixins + 自定义基础应该能够完成几乎所有的事情。
在基础上声明它:
class Base(object):
def get(...):
# ...
Base = declarative_base(cls=Base)
或者使用 mixin。
关于python - SQLAlchemy - Mixin 与 MetaClass 修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6700735/