【问题标题】:SQLAlchemy - Mixin vs MetaClass modificationSQLAlchemy - Mixin vs MetaClass 修改
【发布时间】:2011-07-14 22:31:18
【问题描述】:

比如说,我有两个类:

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)

我想创造一些尽可能少的惊喜。人们对我提出的选项有何看法?是否有更好的方法?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    对于简单的用例,声明式不需要自定义元类,对于困难的用例也几乎不需要。 Mixins + 自定义基础应该可以做几乎所有事情。

    在基础上声明它:

    class Base(object):
        def get(...):
            # ...
    
    Base = declarative_base(cls=Base)
    

    或使用 mixin。

    【讨论】:

      猜你喜欢
      • 2017-10-04
      • 2016-04-30
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多