56 lines
1.9 KiB
Python
56 lines
1.9 KiB
Python
"""Audiobook catalog models."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import ForeignKey, String, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from python.orm.richie.base import TableBase
|
|
|
|
|
|
class AudiobookAuthor(TableBase):
|
|
"""Canonical audiobook author."""
|
|
|
|
__tablename__ = "audiobook_author"
|
|
__table_args__ = (UniqueConstraint("name"),)
|
|
|
|
name: Mapped[str] = mapped_column(String, unique=True)
|
|
|
|
books: Mapped[list[Audiobook]] = relationship("Audiobook", back_populates="author")
|
|
series: Mapped[list[AudiobookSeries]] = relationship("AudiobookSeries", back_populates="author")
|
|
|
|
|
|
class AudiobookSeries(TableBase):
|
|
"""Canonical audiobook series."""
|
|
|
|
__tablename__ = "audiobook_series"
|
|
__table_args__ = (UniqueConstraint("author_id", "name"),)
|
|
|
|
name: Mapped[str] = mapped_column(String)
|
|
author_id: Mapped[int] = mapped_column(ForeignKey("main.audiobook_author.id", ondelete="CASCADE"))
|
|
|
|
author: Mapped[AudiobookAuthor] = relationship("AudiobookAuthor", back_populates="series")
|
|
books: Mapped[list[Audiobook]] = relationship("Audiobook", back_populates="series")
|
|
|
|
|
|
class Audiobook(TableBase):
|
|
"""Canonical audiobook title."""
|
|
|
|
__tablename__ = "audiobook"
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
"author_id",
|
|
"series_id",
|
|
"title",
|
|
postgresql_nulls_not_distinct=True,
|
|
),
|
|
)
|
|
|
|
title: Mapped[str] = mapped_column(String)
|
|
author_id: Mapped[int] = mapped_column(ForeignKey("main.audiobook_author.id", ondelete="CASCADE"))
|
|
series_id: Mapped[int | None] = mapped_column(ForeignKey("main.audiobook_series.id", ondelete="SET NULL"))
|
|
series_index: Mapped[float] = mapped_column(default=0.0)
|
|
|
|
author: Mapped[AudiobookAuthor] = relationship("AudiobookAuthor", back_populates="books")
|
|
series: Mapped[AudiobookSeries | None] = relationship("AudiobookSeries", back_populates="books")
|