2011-07-14 6 views
2

がそう言う修飾:私はクラスの構造を簡素化しましたSQLAlchemyのメタクラス対ミックスインは、例えば、私は二つのクラス持ち、

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機能は、私はベースから継承するすべての私のクラスを越えたいと思いますし、私は最善の方法に見えたことはかなり一般的なものであること、私を襲いましたこれを行う。

  • ミックスインクラス
  • 私は思いメタクラスの変更の

class MyDeclarativeMeta(DeclarativeMeta): 
    def get(self, session, **filterargs): 
    session.query(self).filter_by(**filterargs).one() 

## ... 
Base = declarative_base(metaclass=MyDeclarativeMeta) 

をdeclarative_baseに供給メタクラスを変更する:私は考えることができる2つの方法があります。可能な限り驚きをもって何かを作りたいと思っています。私が提示した選択肢についての人々の意見は何ですか、より良い方法がありますか?

答えて

3

単純なユースケースの場合、Declarativeではカスタムメタクラスは必要ありません。また、ハードユースケースではほとんど使用できません。ミックスイン+カスタムベースは、ほとんどすべてを行うことができるはずです。

は、ベース上でそれを宣言します。

class Base(object): 
    def get(...): 
     # ... 

Base = declarative_base(cls=Base) 

やミックスインを使用します。

+0

私は 'cls'パラメータをどうやって逃したのか分かりません...ありがとう! –

関連する問題