在SqlAlchemy中映射多级类继承层次结构

时间:2014-09-22 17:08:46

标签: python inheritance sqlalchemy hierarchy

背景

我有一个包含3级依赖表的现有数据库。这里我举一个3级联接表的例子,继承映射问题我无法解决。不幸的是我无法改变数据库设计。

问题

如果我执行:

entities = session.query(Entity)
for ent in entities:
    print ent.isin

我收到错误:

AttributeError: 'Asset' object has no attribute 'isin'

但是,以下代码执行正常:

entities = session.query(Entity)
for ent in entities:
    print ent.composition

问题

因此属性composition可以访问,但 isin!?!?

很明显,EntityAsset类正在映射,但不是 Listed。为什么会这样?

我原本相信sqlalchemy能够映射到任意深度的继承。

我已阅读文档,尝试了所有内容,但我感到难过。请帮忙。

继承映射

class Entity(Base):
    __tablename__ = 'entity'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    entity_type = Column('type',String)
    source_table_id = Column(Integer)

    __mapper_args__ = {
        'polymorphic_identity':'entity',
        'polymorphic_on':entity_type,
        }


class Asset(Entity):    
    __tablename__ = 'asset'

    id = Column('entity_id',Integer, ForeignKey('entity.id'), primary_key=True)
    asset_type = Column('type',String)
    asset_class = Column('class',String)
    composition = Column(String)

    __mapper_args__ = {
        'polymorphic_identity':'asset',
        'polymorphic_on':asset_type,
        }


class Listed(Asset):
    __tablename__ = 'listed'

    id = Column('asset_entity_id',Integer, ForeignKey('asset.entity_id'), primary_key=True)
    ticker = Column(String)
    isin = Column(String)

    __mapper_args__ = {
        'polymorphic_identity':'listed',
        }

1 个答案:

答案 0 :(得分:0)

我想也许这只是你数据的巧合。

您应该迭代想要查看的特定类型的对象,例如

entities = session.query(Asset)
for ent in entities:
    print ent.composition

entities = session.query(Listed)
for ent in entities:
    print ent.isin

或在访问该类型对象的属性之前检查对象的类型

entities = session.query(Entity)
for ent in entities:
    if isinstance(ent, Asset):
        print ent.composition
    else isinstance(ent, Listing):
        print ent.isin

否则将要发生的是您将获得一个实体对象,该对象将是ListingAsset对象。如果您对属性isin进行硬编码,那么在处理Asset对象时它将会中断,因为Asset对象没有isin属性。