2013-07-03 29 views
8

tôi sử dụng: Python 2.6 và SQLAlchemy 0.6.1Làm thế nào để xác định metaclass cho một lớp học kéo dài từ SQLAlchemy cơ sở khai báo

Đây là những gì tôi đang cố gắng để làm:

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) 

Và lỗi tôi là nhận được là thế này:

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 

Bây giờ, nếu tôi làm điều tương tự trên bằng cách sử dụng

class Sample(object) 

thay vì

class Sample(Base) 

nó hoạt động hoàn toàn tốt.

Tôi cần cập nhật các thuộc tính của lớp một cách linh hoạt. Vì vậy, tôi sẽ sử dụng thuộc tính động và tên cột. Và tôi cần đoạn mã trên để làm việc để có thể đạt được điều đó.

Xin giúp

Trả lời

8

sử dụng metaclass, nó sẽ phải xuất phát từ Declaratives DeclaredMeta trong trường hợp này. Nhưng không có metaclass là cần thiết cho trường hợp sử dụng này. Sử dụng 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

Nhiều Inheritance .... Genius .... Đúng như dự đoán từ tác giả SQLAlchemy của. – goFrendiAsgard

-1

Nếu đề nghị của đa kế thừa zzzeek không thể giải quyết vấn đề của bạn cố gắng kế thừa metaclass của bạn từ DeclarativeMeta:

from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta 

Base = declarative_base() 

class SampleMeta(DeclarativeMeta): 
    #... 

class Sample(Base): 
    __metaclass__ = SampleMeta 
    #... 
Các vấn đề liên quan