2014-09-22 134 views
0

背景

我有一個具有3級依賴表的現有數據庫。這裏我給出一個3級連接表的示例,我無法解決的繼承映射問題。不幸的是我無法改變數據庫設計。在SqlAlchemy中映射多級別類繼承層次結構

問題

如果我執行:

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', 
     } 
+0

您似乎缺少'Listed'類映射參數中的'polymorphic_on'。 – mjallday 2014-09-22 18:42:44

+1

@ justin-solms:你已經在一個月內三次提出同樣的問題,而且看起來沒有人能幫你解決這個問題。如果你確實需要這麼做,我建議你與'sqlalchemy'的創建者[Mike Bayer](http://techspot.zzzeek.org/)聯繫以獲得建議。 – van 2014-09-23 05:16:48

回答

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屬性。