19

Considering this code (and using SQLAlchemy 0.7.7):

class Document(Base):
    __tablename__ = 'document'
    __table_args__ = {
        'schema': 'app'
    }

    id = Column(types.Integer, primary_key=True)
    nom = Column(types.Unicode(256), nullable=False)
    date = Column(types.Date())

    type_document = Column(types.Enum('arrete', 'photographie',
        name='TYPES_DOCUMENT_ENUM'))
    __mapper_args__ = {'polymorphic_on': type_document}

class Arrete(Document):
    __tablename__ = 'arrete'
    __table_args__ = {
        'schema': 'app'
    }
    __mapper_args__ = {'polymorphic_identity': 'arrete'}

    id = Column(types.Integer, ForeignKey('app.document.id'), primary_key=True)
    numero_arrete = Column(types.Integer)
    date_arrete = Column(types.Date())

I can easily introspect column type for column defined in Arrete class with:

Arrete.__table__.c['date_arrete'].type

But this doesn’t work if I want to access, through the Arrete class, a column defined in Document class. (KeyError if I try to access c['date']).

Is there a way to get column type, regardless if the column is defined in the final class or in one of its parent?

4

3 に答える 3

32

ORM を使用すると、2 つのテーブルの JOIN に対応する継承パターンでクラスを定義できます。この構造は完全なサービスであり、列の属性のタイプなどの基本的なことをほとんど直接見つけるためにも使用できます。

type = Arrete.date.property.columns[0].type

__bases__これは、Python の通常のクラス メカニクスに任せることを除けば、基本的に を通り抜けるアプローチと同じであることに注意してください。

于 2012-07-24T15:57:26.247 に答える
7

基本クラスを探索できます...

def find_type(class_, colname):
    if hasattr(class_, '__table__') and colname in class_.__table__.c:
        return class_.__table__.c[colname].type
    for base in class_.__bases__:
        return find_type(base, colname)
    raise NameError(colname)

print find_type(Arrete, 'date_arrete')
print find_type(Arrete, 'date')
于 2012-07-24T14:58:45.493 に答える
0

抽象的な特別なディレクティブまたはmixin パターンが必要です。

ミックスインの場合、次のようなものを使用します。

class MyMixin(object):
    __tablename__ = 'document'
    __table_args__ = {
        'schema': 'app'
    }

    id = Column(types.Integer, primary_key=True)
    nom = Column(types.Unicode(256), nullable=False)
    date = Column(types.Date())

class Arrete(MyMixin, Base):
    __tablename__ = 'arrete'

    __mapper_args__ = {'polymorphic_identity': 'arrete'}

    foreign_id = Column(types.Integer, ForeignKey('app.document.id'), primary_key=True)
    numero_arrete = Column(types.Integer)
    date_arrete = Column(types.Date())


class Document(MyMixin, Base):
    __tablename__ = 'Document'
    type_document = Column(types.Enum('arrete', 'photographie',
        name='TYPES_DOCUMENT_ENUM'))
    __mapper_args__ = {'polymorphic_on': type_document}

共有されたものは mixin に入り、共有されていないものはサブクラスに入ります。

于 2012-07-24T14:29:09.937 に答える