Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy: Multiple foreign keys to same table with compound primary key

In SQLAlchemy, imagine we have a table Foo with a compound primary key, and Bar, which has two foreign key constrains linking it to Foo (each Bar has two Foo objects).

My problem is with the relationship function, which makes me repeat the information (in the primaryjoin) which I have already given in the ForeightKeyConstraint (violating DRY). Is there some other way of structuring this so that I don't have to repeat information? Some way of passing the relevant ForeignKeyConstraint to relationship?

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

Thanks.

like image 551
DaedalusFall Avatar asked Jan 15 '12 19:01

DaedalusFall


People also ask

Can you have multiple foreign keys from the same table?

A table can have multiple foreign keys based on the requirement.

Can two foreign keys reference the same primary key?

It is perfectly fine to have two foreign key columns referencing the same primary key column in a different table since each foreign key value will reference a different record in the related table.

Can foreign key be repeated more than once in a table?

A foreign key can contain duplicate values. There is no limitation in inserting the values into the table column.

Can we create foreign key on same table?

FOREIGN KEY constraints can reference another column in the same table, and is referred to as a self-reference. A FOREIGN KEY constraint specified at the column level can list only one reference column. This column must have the same data type as the column on which the constraint is defined.


2 Answers

The relationship(), as it is, cannot determine its full configuration. This is always the case when there is more than one way to refer to the related table.
In your example it seems like sqlalchemy could be smart enough to guess by the names of the columns, but this is not what does and it should not.

Although it might seem as if you have information repetition, in fact you are just being specific about your relationship configuration.

There is, in fact, option to specify foreign_keys in the relationship() configuration, but currently is serves somewhat different purpose, so you still will need to configure primaryjoin.

like image 71
van Avatar answered Oct 13 '22 00:10

van


You can also use foreign_keys and a list of Foreign Keys.

See 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])
like image 27
jackotonye Avatar answered Oct 12 '22 23:10

jackotonye