2017-06-25 57 views
1

我需要使用經典映射,而不是聲明,在過去的兩天我試圖使繼承工作,我嘗試了聲明式風格,它的工作,但無論我嘗試我不能讓它在使用舊的映射風格時能夠正常工作。SQLAlchemy,與經典映射的多態繼承

class Item(object): 

    def specialised_method(self): 
     return "I am not special" 


class SpecialisedItem(Item): 
    __mapper_args__ = { 
     'polymorphic_identity': 'special', 
    } 

    def specialised_method(self): 
     return "I am special" 

orm.mapper(Item, enviroment.tables.items, 
      polymorphic_on=enviroment.tables.items.c.type, 
      polymorphic_identity="normal") 


# orm.mapper(SpecialisedItem, enviroment.tables.items,polymorphic_on=enviroment.tables.items.c.type,polymorphic_identity='special') 

def test_inheritance(request): 
    enviroment=get_enviroment() 
    session=enviroment.session 
    for item in session.query(Item).filter_by(type="special"): 
     print(item.type,item.specialised_method(),item) 

拋出:

AssertionError: No such polymorphic_identity 'special' is defined 

如果我從項目mapper_args那麼項目的特殊方法被調用刪除polymorphic_identity =「正常」,這似乎SpecialisedItem永遠不會被視爲項目的一個子。

回答

2

問題可能是您沒有將繼承信息傳遞給mapper。在使用經典映射時,不會推斷出繼承結構

嘗試類似:

class Item(object): 
    def specialised_method(self): 
     return "I am not special" 

class SpecialisedItem(Item): 
    def specialised_method(self): 
     return "I am special" 

orm.mapper(Item, enviroment.tables.items, 
      polymorphic_on=enviroment.tables.items.c.type, 
      polymorphic_identity="normal") 

orm.mapper(SpecialisedItem, 
      enviroment.tables.items, 

      # you need to specify the parent 
      inherits=Item, 
      polymorphic_identity='special') 

注意,沒有必要在映射到指定polymorphic_onSpecialisedItem。通常,如果在基礎表之間存在適當的外鍵,則會推斷出,並且在這裏您使用的是相同的基礎表,因此該點是mout。

+0

謝謝......這可能是我的文檔閱讀技巧,但我認爲sqlalchemy在使用非聲明式樣式時缺少文檔。你的代碼有效。 – SteveL