Dear all, I am currently reworking a bit of my model and stumbled into this question, which I think mainly has opinionated answers - but I would like to have some insight regarding SQLAlchemy usage or preferences.
I have a situation where I am in the exact same case like the one described in the Association Object <https://docs.sqlalchemy.org/en/20/orm/basic_relationships.html#association-object> in the SQLAlchemy ORM docs. I want to modelize : - Caregiver - a person taking care of one or more Helpee - Helpee - a person who is being taken care of, by one or more Caregiver - their Relationship, which links a Caregiver to a Helpee, but with additional data like their family ties (spouse, parent, friend, ...) This is typically the Association object use case, a many to many relationship, holding additional data. So far, I have been using a "natural" primary key on the Relationship table, by using the Caregiver Id, and the Helpee Id to form a composite primary key. >From a handful of blog posts (this StackOverflow answer <https://dba.stackexchange.com/a/6110> being quite in depth), it looks like adding an "artificial" or surrogate primary key on the Relationship table should be the way to go. Of course, I would keep a unique constraint on (Caregiver Id x Helpee Id) on this table along the new primary key. My questions are : - is the addition of a surrogate primary key a good idea - without taking into account the fact that I am using SQLAlchemy? - would the "magic" of the association object still operate even though the mapped ORM relationships would not be part of the primary key anymore? The docs example would become: from typing import Optional from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy.orm import Mapped from sqlalchemy.orm import mapped_column from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import relationship class Base(DeclarativeBase): pass class Association(Base): __tablename__ = "association_table" * id: Mapped[int] = mapped_column(primary_key=True)* left_id: Mapped[int] = mapped_column(ForeignKey("left_table.id")*, primary_key=True*) right_id: Mapped[int] = mapped_column( ForeignKey("right_table.id")*, primary_key=True* ) extra_data: Mapped[Optional[str]] child: Mapped["Child"] = relationship(back_populates="parents") parent: Mapped["Parent"] = relationship(back_populates="children") * __table_args__ = (UniqueConstraint('left_id', 'right_id', name='_relationship_uc'),)* class Parent(Base): __tablename__ = "left_table" id: Mapped[int] = mapped_column(primary_key=True) children: Mapped[List["Association"]] = relationship(back_populates="parent") class Child(Base): __tablename__ = "right_table" id: Mapped[int] = mapped_column(primary_key=True) parents: Mapped[List["Association"]] = relationship(back_populates="child") -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/CAH4TWVvPVKtjtyVHJO9WtX2ZCjmdX3aGWDBGCQrvU_7c-CswEg%40mail.gmail.com.