2013-07-03 51 views
8

uzanan sınıf için metaclass nasıl tanımlanır:bir kullandığım sqlalchemy bildirime tabanından

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) 

Ve hata I: Python 2.6 ve sqlalchemy 0.6.1

Bu yapmak ne çalışıyorum ben alıyorum şudur: Şimdi

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 

Ben

class Sample(object) 
kullanarak yukarıdaki aynı şeyi yaparsan

yerine

class Sample(Base) 

arasında kesinlikle çalışıyor.

Sınıfın özniteliklerini dinamik olarak güncelleştirmem gerekiyor. Yani, dinamik özellik ve sütun isimleri kullanıyorum. Ve oraya ulaşmak için çalışmak için yukarıdaki parça koduna ihtiyacım var.

cevap

8

metaclass kullanmayı yardım edin, bu durumda bildirim deyimleri DeclaredMeta kaynaklanıyor gerekecekti. Ancak bu kullanım durumu için hiçbir metacama gerek yoktur. mixins kullanın:

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

Çoklu Kalıtım .... Genius .... sqlalchemy en yaratıcısı Beklendiği gibi. – goFrendiAsgard

-1

senin sorunun DeclarativeMeta adresinin metaclass miras denemek çözemez zzzeek çoklu miras önerdiği edin:

from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta 

Base = declarative_base() 

class SampleMeta(DeclarativeMeta): 
    #... 

class Sample(Base): 
    __metaclass__ = SampleMeta 
    #...