2013-02-14 61 views
9

我有一個父表稱爲pbx_point具有point_type列。我還有一個名爲pbx_route的子表,其中有一個名爲point_id的列指向pbx_point在sqlalchemy中,當子表有多個外鍵到父表時,如何使用多態聯接表繼承?

我想使用SQLAlchemy的連接表繼承涉及通過聲明的基礎這兩個表,並使用多態繼承

這工作得很好 - 或者更確切地說,它會,如果不是下面的附加約束:pbx_point還有一個名爲initial_route_id的外鍵指向pbx_route

我還使用反射下面,但db是如我如上所述。我得到的錯誤是sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'pbx_point' and 'pbx_route'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly.

這是有意義的,因爲「幕後」 delcarative鹼創建兩個映射類的關係()屬性。我希望它選擇pbx_route.point_id作爲parent_id鏈接,但它也會看到pbx_point.initial_route_id列。如果我創建這個關係(),這將很容易解決,但我不是 - 聲明式繼承系統。

是否有一個額外的參數,我可以傳遞給__mapper_args__,比如polymorphic_parent_col這會讓我指定我想要的外鍵?如果沒有,我該如何解決這個問題?

謝謝。

class MyBase(DeferredReflection): 
    @declared_attr 
    def __tablename__(cls): 
     return cls.__name__.lower() 

Base = declarative_base(cls=MyBase) 

class pbx_point(Base): 
    __mapper_args__ = dict(
     polymorphic_on='point_type', 
     with_polymorphic='*', 
    ) 

class pbx_route(pbx_point): 
    __mapper_args__ = dict(polymorphic_identity='pbx.route') 

這是堆棧跟蹤我得到:

Traceback (most recent call last): 
    File "db.py", line 50, in <module> 
    Base.prepare(engine) 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 431, in prepare 
    thingy.map() 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 379, in map 
    **mapper_args 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/orm/__init__.py", line 1147, in mapper 
    return Mapper(class_, local_table, *args, **params) 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 213, in __init__ 
    self._configure_inheritance() 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 517, in _configure_inheritance 
    self.local_table) 
    File "env/local/lib/python2.7/site-packages/sqlalchemy/sql/util.py", line 397, in join_condition 
    "join explicitly." % (a.description, b.description)) 
sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'pbx_point' and 'pbx_route'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. 

這表明它正在死去的https://bitbucket.org/sqlalchemy/sqlalchemy/src/7f3494ebad58/lib/sqlalchemy/orm/mapper.py?at=default#cl-517。上面的幾行代表映射器kwarg inherit_condition,這似乎是我需要的。

回答

10

關鍵是映射器的參數inherit_condition。多態信息實際上與這一步沒有任何關係。

修正模型:

class MyBase(DeferredReflection): 
    @declared_attr 
    def __tablename__(cls): 
     return cls.__name__.lower() 

Base = declarative_base(cls=MyBase) 

class pbx_point(Base): 
    __mapper_args__ = dict(
     polymorphic_on='point_type', 
     with_polymorphic='*', 
    ) 
    id = Column(Integer, primary_key=True) 

class pbx_route(pbx_point): 
    point_id = Column(Integer, ForeignKey(pbx_point.id)) 
    __mapper_args__ = dict(
     polymorphic_identity='pbx.route', 
     inherit_condition=(point_id == pbx_point.id) 
    ) 

我需要添加idpoint_id列在inherit_condition參數使用它們。有可能只有使用反射才能做到這一點,但這不是一個可怕的障礙。

+1

我有這個確切的問題,並沒有找到它在文檔中。感謝你的回答。 – 2015-09-15 03:03:03

相關問題