2013-02-14 2 views
9

point_typeの列を持つpbx_pointという親テーブルがあります。 pbx_routeという子テーブルもあります。point_idという列はpbx_pointを指します。sqlalchemyでは、子テーブルに親テーブルへの複数の外部キーがある場合、どのように多相結合テーブル継承を使用できますか?

私は、宣言型のベースを経由して、これらの2つのテーブルを関連付けるためにSQLAlchemyのの結合テーブル継承を使用したい、と。これは、正常に動作します多型の継承に

を使用したい - というか、それがなり、そうでない場合は、以下の追加の制約のために:pbx_pointinitial_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.です。

これは意味があります。デコレーティブベースはマッピングされたクラスの両方にrelationship()属性を作成しているため、意味があります。 parent_idリンクにpbx_route.point_idを選択したいのですが、それにはpbx_point.initial_route_idという列もあります。これは、私がこの関係()を作成していれば修正するのは簡単でしょうが、私はそうではありません - 宣言的継承システムがあります。

__mapper_args__に渡すことができる追加の引数がありますか?polymorphic_parent_colなど、私が望む外来キーを指定できますか?そうでない場合は、どうすればこの問題を回避できますか?

ありがとうございました。

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で死にかけていることを示し:

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') 

この

は私が取得していますスタックトレースです。上記の数行は、マッパー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) 
    ) 

私はinherit_condition引数でそれらを使用するidpoint_id列を追加するために必要な:

は、モデルを修正しました。反射を使用してこれを行う方法がある可能性がありますが、これはひどい障害ではありません。

+1

私はこの正確な問題を抱えていて、ドキュメントで見つけることができませんでした。答えをありがとう。 –

関連する問題