2012-01-15 11 views
5

と同じテーブルに複数の外部キー、我々はFooにリンクする2つの外部キー制約を有する化合物の主キー、及びBarとテーブルFooを有する想像する(各Barは、二つFooオブジェクトを有します)。SQLAlchemyの:SQLAlchemyの中の化合物の主キー

私の問題は、ForeightKeyConstraint(DRYに違反しています)で既に述べた情報(primaryjoin)を繰り返すrelationship機能に問題があります。私は情報を繰り返す必要がないようにこれを構造化する他の方法がありますか?関連するForeignKeyConstraintrelationshipに渡す方法はありますか?

class Foo(Base): 
    __tablename__ = "Foo" 
    id_1 = Column(Integer, primary_key=True) 
    id_2 = Column(Integer, primary_key=True) 

class Bar(Base): 
    __tablename__ = "Bar" 
    id = Column(Integer, primary_key=True) 

    foo_1_id_1 = Column(Integer) 
    foo_1_id_2 = Column(Integer) 

    foo_2_id_1 = Column(Integer) 
    foo_2_id_2 = Column(Integer) 

    __table_args__ = (
      ForeignKeyConstraint(
       [foo_1_id_1,foo_1_id_2], 
       [Foo.id_1,Foo.id_2] 
       ), 
      ForeignKeyConstraint(
       [foo_2_id_1,foo_2_id_2], 
       [Foo.id_1,Foo.id_2] 
       ) 
      ) 

    foo_1 = relationship(Foo,primaryjoin="(Bar.foo_1_id_1 == Foo.id_1) & (Bar.foo_1_id_2 == Foo.id_2)") 
    foo_2 = relationship(Foo,primaryjoin="(Bar.foo_2_id_1 == Foo.id_1) & (Bar.foo_2_id_2 == Foo.id_2)") 

ありがとうございます。

答えて

2

relationship()はそのままで完全な構成を決定することはできません。関連するテーブルを参照する方法が複数ある場合は常にそうです。
あなたの例では、sqlalchemyが列の名前で推測するのに十分スマートであるかもしれないようですが、これは何かではなく、そうではありません。

あなたは情報繰り返しを持っているかのように、実際にあなたがちょうどはあなたの関係の構成に関する特定されている、ように見えるかもしれないが。

relationship()の設定では、実際にはforeign_keysを指定するオプションがありますが、現在は多少異なる目的を果たしているため、primaryjoinを設定する必要があります。

+0

感謝を参照してください。しかし繰り返しがあります。私はそれが使用する 'ForeignKeyConstraint'を知りません。しかし、例えば、関係の 'ForeignKeyConstraint'への参照を何らかの形で' relationship'に与えることができ、それが与えられたテーブルに対してただ一つの 'ForeignKeyConstraint'があるときと同じように、その場合、結合の詳細が繰り返されなくなります。 – DaedalusFall

+0

実際、言及したように、関係に 'foreign_keys'を提供する可能性がありますが、現在は' primaryjoin'条件を推論するために使用されていません。あなたのケースは、このように使用できる良い例です。しかし、答えに記載されているように、*現在*それはありません。しかし、なぜ機能要求チケットをhttp://www.sqlalchemy.org/trac/に作成しないのですか? – van

+0

私はそれから、私が今までにほとんどの場合明らかにしている何かを明らかにしていないことを確認したいと思っていました私のSQLAlchemy不具合! – DaedalusFall

0

また、foreign_keysと外部キーのリストを使用することもできます。

Multiple Join Paths

foo_1 = relationship(Foo, foreign_keys=[foo_1_id_1, foo_2_id_2]) 
foo_2 = relationship(Foo, foreign_keys=[foo_2_id_1, foo_2_id_2]) 
関連する問題