"""Movie entity and its directly-owned satellite tables (section 4).""" from __future__ import annotations import uuid from datetime import date from sqlalchemy import BigInteger, Date, Float, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin from app.models.collection import Collection from app.models.enums import MovieStatus class Movie(Base, UUIDPrimaryKeyMixin, TimestampMixin): __tablename__ = "movies" title: Mapped[str] = mapped_column(String(500), nullable=False, index=True) original_title: Mapped[str | None] = mapped_column(String(500), nullable=True) # Title with leading articles ("The", "A") stripped, for stable sorting. sort_title: Mapped[str] = mapped_column(String(500), nullable=False, index=True) overview: Mapped[str | None] = mapped_column(Text, nullable=True) tagline: Mapped[str | None] = mapped_column(Text, nullable=True) status: Mapped[MovieStatus] = mapped_column(default=MovieStatus.RELEASED, nullable=False) original_language_code: Mapped[str | None] = mapped_column( ForeignKey("languages.code"), nullable=True ) primary_release_date: Mapped[date | None] = mapped_column(Date, nullable=True, index=True) runtime_minutes: Mapped[int | None] = mapped_column(Integer, nullable=True) budget: Mapped[int | None] = mapped_column(BigInteger, nullable=True) revenue: Mapped[int | None] = mapped_column(BigInteger, nullable=True) popularity: Mapped[float | None] = mapped_column(Float, nullable=True) vote_average: Mapped[float | None] = mapped_column(Float, nullable=True) vote_count: Mapped[int | None] = mapped_column(Integer, nullable=True) adult: Mapped[bool] = mapped_column(default=False, nullable=False) collection_id: Mapped[uuid.UUID | None] = mapped_column( ForeignKey("collections.id", ondelete="SET NULL"), nullable=True ) # Best-known authoritative source for this record at creation time. Full # field-level provenance lives in provider_records; this is a coarse # pointer for quick display. See docs/architecture.md. source_provider_id: Mapped[uuid.UUID | None] = mapped_column( ForeignKey("providers.id", ondelete="SET NULL"), nullable=True ) collection: Mapped[Collection | None] = relationship() class MovieAlternateTitle(Base, UUIDPrimaryKeyMixin): __tablename__ = "movie_alternate_titles" movie_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("movies.id", ondelete="CASCADE"), nullable=False, index=True ) title: Mapped[str] = mapped_column(String(500), nullable=False) country_code: Mapped[str | None] = mapped_column(ForeignKey("countries.code"), nullable=True) type: Mapped[str | None] = mapped_column(String(50), nullable=True) # e.g. "working_title" class MovieSpokenLanguage(Base): __tablename__ = "movie_spoken_languages" movie_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("movies.id", ondelete="CASCADE"), primary_key=True ) language_code: Mapped[str] = mapped_column( ForeignKey("languages.code"), primary_key=True ) class MovieProductionCountry(Base): __tablename__ = "movie_production_countries" movie_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("movies.id", ondelete="CASCADE"), primary_key=True ) country_code: Mapped[str] = mapped_column(ForeignKey("countries.code"), primary_key=True) class ReleaseDate(Base, UUIDPrimaryKeyMixin): """Per-country/per-type release dates and certifications for a movie.""" __tablename__ = "release_dates" entity_type: Mapped[str] = mapped_column(String(30), default="movie", nullable=False) entity_id: Mapped[uuid.UUID] = mapped_column(nullable=False, index=True) country_code: Mapped[str] = mapped_column(ForeignKey("countries.code"), nullable=False) release_date: Mapped[date] = mapped_column(Date, nullable=False) # "theatrical", "digital", "physical", "premiere", "tv" release_type: Mapped[str | None] = mapped_column(String(50), nullable=True) certification_id: Mapped[uuid.UUID | None] = mapped_column( ForeignKey("certifications.id", ondelete="SET NULL"), nullable=True ) note: Mapped[str | None] = mapped_column(Text, nullable=True) class MovieRecommendation(Base): """Recommendations/similar-title edges between movies.""" __tablename__ = "movie_recommendations" movie_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("movies.id", ondelete="CASCADE"), primary_key=True ) recommended_movie_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("movies.id", ondelete="CASCADE"), primary_key=True ) rank: Mapped[int | None] = mapped_column(Integer, nullable=True) source: Mapped[str | None] = mapped_column(String(50), nullable=True) __all__ = [ "Movie", "MovieAlternateTitle", "MovieSpokenLanguage", "MovieProductionCountry", "ReleaseDate", "MovieRecommendation", ]