So say, for example I have two classes:
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):
sel开发者_开发问答f.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)
I've simplified the class structure, now, using these classes, I can use:
sql = sqlschema.SQLSchema()
So, at times, I want easy access to a Vendor, which means I can use:
v = sql.session.query(self).filter_by(name='test').one()
I'd prefer to simplify the access by using akin to (currently my best effort):
Vendor.get(sql.session, name='A-01')
It struck me, that the get
function is pretty generic that I'd want across all my classes that inherit from Base and I looked into the best way of doing this. There are two ways I can think of:
- a Mix-in class
- Modifying the metaclass supplied to declarative_base
Example of the metaclass modification
class MyDeclarativeMeta(DeclarativeMeta):
def get(self, session, **filterargs):
session.query(self).filter_by(**filterargs).one()
## ...
Base = declarative_base(metaclass=MyDeclarativeMeta)
I'd like to create something with the least surprise possible. What are people's opinions on the options I've presented and is there a better way altogether?
Custom metaclasses aren't needed with Declarative for simple use cases, and pretty much not at all for hard use cases either. Mixins + custom bases should be able to do pretty much everything.
Declare it on the base:
class Base(object):
def get(...):
# ...
Base = declarative_base(cls=Base)
or use a mixin.
精彩评论