Why are the foreign keys in a SQLAlchemy Association Object marked as primary keys?
Below is the documentation from sqlalchemy.
Notice how for left_id and right_id in the Association Class, they are first marked as ForeignKey and then primary_key = True
It makes sense to me that they should be foreign keys because logically they are foreign keys to the other two parent and child tables.
So whats the purpose of having them be primary keys as well?
Whats going on here? Please explain.
作者: Benjamin Kozuch 的来源 发布者： 2017 年 12 月 27 日
class Association(Base): __tablename__ = 'association' left_id = Column(Integer, ForeignKey('left.id'), primary_key=True) right_id = Column(Integer, ForeignKey('right.id'), primary_key=True) extra_data = Column(String(50)) child = relationship("Child", back_populates="parents") parent = relationship("Parent", back_populates="children") class Parent(Base): __tablename__ = 'left' id = Column(Integer, primary_key=True) children = relationship("Association", back_populates="parent") class Child(Base): __tablename__ = 'right' id = Column(Integer, primary_key=True) parents = relationship("Association", back_populates="child")
This is not unique to SQLAlchemy. This is how
many-to-many relationships are designed, which is based on the principles of Relational Database design.
In a many-to-many relationship, there is a need for an additional table, also called association table, which maps entries from the first table with corresponding entries from the second table.
When the association table is defined, we need some primary key to uniquely identify records in the association table. Having a primary key creates an index, which speeds up joining operations and the search for records.
So, why have all the Foreign keys as a part of the Primary for the association table?
This is to make sure there are no duplicate entries of record
table A and record
Table B. In other words, to ensure uniqueness in the relationship, thus, avoiding duplication of relationships.
Association table can be created without declaring the Foreign keys as Primary keys. But this is not advisable. By doing so, the join operations become slow unless indexes are created explicitly. And, there is a good chance of having duplicated records of a relationship between
Table A and