2013-07-03 54 views
8

延伸的I類使用:Python的2.6和SQLAlchemy的0.6.1如何定義元類爲從SQLAlchemy的聲明基礎

這就是我要做的:

from sqlalchemy.types import (
    Integer, 
    String, 
    Boolean 
) 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class SampleMeta(type): 
    def __new__(cls, name, bases, attrs): 
     attrs.update({ 'id': Column('Id', Integer, primary_key=True), 
        'name': Column('Name', String), 
        'description': Column('Description', String), 
        'is_active': Column('IsActive', Boolean) 
       }) 
     return super(SampleMeta, cls).__new__(cls, name, bases, attrs) 

class Sample(Base): 
    __tablename__ = 'Sample' 
    __table_args__ = {'useexisting': True} 
    __metaclass__ = SampleMeta 

    def __init__(self, id, name, description, is_active): 
     self.id = id 
     self.name = name 
     self.description = description 
     self.is_active = is_active 

    def __repr__(self): 
     return "<(%d, '%s', '%s', %r)>" % (self.id, self.name, self.description, self.isactive) 

和錯誤我我得到的是:

TypeError: Error when calling the metaclass bases 
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases 

現在,如果我用

class Sample(object) 
上面做同樣的事情

代替

class Sample(Base) 

它工作絕對沒問題。

我需要動態更新類的屬性。所以,我將使用動態屬性和列名稱。我需要上面的代碼才能工作才能到達那裏。

請幫

回答

8

使用元類,那就得從陳述句DeclaredMeta在這種情況下獲得。但是這個用例不需要元類。如果提出zzzeek多重繼承解決不了你的問題試圖從DeclarativeMeta繼承你的MetaClass

from sqlalchemy.types import (
    Integer, 
    String, 
    Boolean 
) 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column 

Base = declarative_base() 

class SampleMixin(object): 
    id = Column("Id", Integer, primary_key=True) 
    name = Column("Name", String) 
    description = Column("Description", String) 
    is_active = Column("IsActive", Boolean) 

class Sample(SampleMixin, Base): 
    __tablename__ = 'Sample' 
    __table_args__ = {'useexisting': True} 

    def __init__(self, id, name, description, is_active): 
     self.id = id 
     self.name = name 
     self.description = description 
     self.is_active = is_active 

    def __repr__(self): 
     return "<(%d, '%s', '%s', %r)>" % (self.id, self.name, 
           self.description, self.isactive) 

from sqlalchemy import select 
print select([Sample.id, Sample.name]) 
+0

多重繼承....天才....作爲從SQLAlchemy的創建者的預期。 – goFrendiAsgard

-1

:使用mixins

from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta 

Base = declarative_base() 

class SampleMeta(DeclarativeMeta): 
    #... 

class Sample(Base): 
    __metaclass__ = SampleMeta 
    #... 
相關問題