refactor: use unique constraints instead of composite keys on link tables

This commit is contained in:
2026-08-10 23:58:09 -04:00
parent 9fe69641c5
commit c5b703b75a
4 changed files with 17 additions and 23 deletions
+4 -5
View File
@@ -1,7 +1,7 @@
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Optional
from collections.abc import Hashable from collections.abc import Hashable
from sqlalchemy import ColumnElement, ForeignKey from sqlalchemy import ColumnElement, ForeignKey, UniqueConstraint
from sqlalchemy.orm import Mapped from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
@@ -35,11 +35,10 @@ class Author(BigIntAuditBase, UniqueMixin):
class BookAuthorLink(BigIntBase): class BookAuthorLink(BigIntBase):
__tablename__ = "book_author_links" __tablename__ = "book_author_links"
__table_args__ = (UniqueConstraint("book_id", "author_id"),)
book_id: Mapped[int] = mapped_column( book_id: Mapped[int] = mapped_column(ForeignKey("books.id", ondelete="cascade"))
ForeignKey("books.id", ondelete="cascade"), primary_key=True author_id: Mapped[int] = mapped_column(ForeignKey("authors.id"))
)
author_id: Mapped[int] = mapped_column(ForeignKey("authors.id"), primary_key=True)
position: Mapped[int] position: Mapped[int]
+4 -6
View File
@@ -1,8 +1,7 @@
from datetime import date from datetime import date
from typing import TYPE_CHECKING, Any, Optional from typing import TYPE_CHECKING, Any, Optional
from sqlalchemy import Index from sqlalchemy import Index, ForeignKey, UniqueConstraint
from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.orm import mapped_column from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
@@ -127,11 +126,10 @@ class Book(BigIntAuditBase):
class Identifier(BigIntBase): class Identifier(BigIntBase):
__tablename__ = "identifiers" __tablename__ = "identifiers"
__table_args__ = (UniqueConstraint("name", "book_id"),)
name: Mapped[str] = mapped_column(primary_key=True) name: Mapped[str]
book_id: Mapped[int] = mapped_column( book_id: Mapped[int] = mapped_column(ForeignKey("books.id", ondelete="cascade"))
ForeignKey("books.id", ondelete="cascade"), primary_key=True
)
value: Mapped[str] value: Mapped[str]
def __repr__(self): def __repr__(self):
@@ -1,5 +1,5 @@
from typing import Optional from typing import Optional
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy
from sqlalchemy.ext.orderinglist import ordering_list from sqlalchemy.ext.orderinglist import ordering_list
@@ -38,10 +38,10 @@ class BookList(BigIntAuditBase):
class BookListLink(BigIntBase): class BookListLink(BigIntBase):
__tablename__ = "book_list_links" __tablename__ = "book_list_links"
book_id: Mapped[int] = mapped_column( __table_args__ = (UniqueConstraint("book_id", "list_id"),)
ForeignKey("books.id", ondelete="cascade"), primary_key=True
) book_id: Mapped[int] = mapped_column(ForeignKey("books.id", ondelete="cascade"))
list_id: Mapped[int] = mapped_column(ForeignKey("book_lists.id"), primary_key=True) list_id: Mapped[int] = mapped_column(ForeignKey("book_lists.id"))
position: Mapped[int] position: Mapped[int]
book: Mapped[Book] = relationship(back_populates="list_links") book: Mapped[Book] = relationship(back_populates="list_links")
+4 -7
View File
@@ -1,7 +1,7 @@
from collections.abc import Hashable from collections.abc import Hashable
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from sqlalchemy import ColumnElement, ForeignKey from sqlalchemy import ColumnElement, ForeignKey, UniqueConstraint
from sqlalchemy.orm import Mapped from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
@@ -35,15 +35,12 @@ class Tag(BigIntBase, UniqueMixin):
class BookTagLink(BigIntBase): class BookTagLink(BigIntBase):
__tablename__ = "book_tag_link" __tablename__ = "book_tag_link"
__table_args__ = (UniqueConstraint("book_id", "tag_id"),)
book_id: Mapped[int] = mapped_column( book_id: Mapped[int] = mapped_column(ForeignKey("books.id", ondelete="cascade"))
ForeignKey("books.id", ondelete="cascade"), primary_key=True tag_id: Mapped[int] = mapped_column(ForeignKey("tags.id"))
)
tag_id: Mapped[int] = mapped_column(ForeignKey("tags.id"), primary_key=True)
position: Mapped[int] position: Mapped[int]
book: Mapped["Book"] = relationship(back_populates="tag_links") book: Mapped["Book"] = relationship(back_populates="tag_links")
tag: Mapped[Tag] = relationship() tag: Mapped[Tag] = relationship()