2013-07-03 4 views
8

ich benutze: Python 2.6 und sqlalchemy 0.6.1Wie Metaklasse für eine Klasse zu definieren, die von sqlalchemy deklarative Basis erstreckt

Dies ist, was ich zu tun versucht:

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) 

Und die Fehler, die ich bin immer ist dies:

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 

Nun, wenn ich das gleiche tun oben

class Sample(object) 
mit

statt

class Sample(Base) 

funktioniert es absolut in Ordnung.

Ich muss die Attribute der Klasse dynamisch aktualisieren. Also werde ich dynamische Attribut- und Spaltennamen verwenden. Und ich brauche den obigen Code um zu arbeiten.

Bitte helfen

Antwort

8

die Metaklasse zu verwenden, müsste sie von DECLARATIVES DeclaredMeta in diesem Fall abzuleiten. Für diesen Anwendungsfall wird jedoch keine Metaklasse benötigt. Verwenden Sie mixins:

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

Mehrfachvererbung .... Genius .... Als Schöpfer von SQLAlchemy erwarteten. – goFrendiAsgard

-1

Wenn durch zzzeek Mehrfachvererbung vorgeschlagen kann Ihr Problem nicht lösen versuchen erben Ihre MetaClass von DeclarativeMeta:

from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta 

Base = declarative_base() 

class SampleMeta(DeclarativeMeta): 
    #... 

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