from typing import List from sqlalchemy import ForeignKey, UniqueConstraint from sqlalchemy.orm import relationship, mapped_column, Mapped from src.db.models.base import Base, BaseMixin class Sport(Base, BaseMixin): __tablename__ = "sport" __table_args__ = ( UniqueConstraint("name"), ) name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True) teams: Mapped[List["Team"]] = relationship(back_populates="sport") positions: Mapped[List["FieldPosition"]] = relationship(back_populates="sport") class Team(Base, BaseMixin): __tablename__ = "team" name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True) short_name: Mapped[str] = mapped_column(nullable=False) sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False) sport: Mapped[Sport] = relationship(back_populates="teams") roosters: Mapped[List["Rooster"]] = relationship(back_populates="team") class FieldPosition(Base, BaseMixin): __tablename__ = "field_position" __table_args__ = ( UniqueConstraint("name", "sport_id"), UniqueConstraint("short_name", "sport_id"), ) name: Mapped[str] = mapped_column(nullable=False, index=True) short_name: Mapped[str] = mapped_column(nullable=False) sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False, index=True) sport: Mapped[Sport] = relationship(back_populates="positions") roosters: Mapped[List["Rooster"]] = relationship(back_populates="position") class Player(Base, BaseMixin): __tablename__ = "player" __table_args__ = ( UniqueConstraint("first_name", "last_name"), ) first_name: Mapped[str] = mapped_column(nullable=False, index=True) last_name: Mapped[str] = mapped_column(nullable=False, index=True) roosters: Mapped[List["Rooster"]] = relationship(back_populates="player") def get_full_name(self) -> str: return f"{self.last_name}, {self.first_name}" class Rooster(Base, BaseMixin): __tablename__ = "rooster" __table_args__ = ( UniqueConstraint("year", "team_id", "player_id", "position_id"), ) year: Mapped[int] team_id: Mapped[str] = mapped_column(ForeignKey("team.id"), nullable=False, index=True) team: Mapped[Team] = relationship(back_populates="roosters") player_id: Mapped[str] = mapped_column(ForeignKey("player.id"), nullable=False, index=True) player: Mapped[Player] = relationship(back_populates="roosters") position_id: Mapped[str] = mapped_column(ForeignKey("field_position.id"), nullable=False, index=True) position: Mapped[FieldPosition] = relationship(back_populates="roosters") cards: Mapped[List["Card"]] = relationship(back_populates="rooster") class Vendor(Base, BaseMixin): __tablename__ = "vendor" name: Mapped[str] = mapped_column(nullable=False, unique=True, index=True) card_sets: Mapped[List["CardSet"]] = relationship(back_populates="vendor") cards: Mapped[List["Card"]] = relationship(back_populates="vendor") class CardSet(Base, BaseMixin): __tablename__ = "card_set" __table_args__ = ( UniqueConstraint("name", "vendor_id"), ) name: Mapped[str] = mapped_column(index=True) parallel_set: Mapped[bool] insert_set: Mapped[bool] vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False, index=True) vendor: Mapped[Vendor] = relationship(back_populates="card_sets") cards: Mapped[List["Card"]] = relationship(back_populates="card_set") class Card(Base, BaseMixin): __tablename__ = "card" __table_args__ = ( UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), ) card_number: Mapped[int] = mapped_column(index=True) year: Mapped[int] = mapped_column(index=True) card_set_id: Mapped[str] = mapped_column(ForeignKey("card_set.id"), nullable=False) card_set: Mapped[CardSet] = relationship(back_populates="cards") rooster_id: Mapped[str] = mapped_column(ForeignKey("rooster.id"), nullable=False) rooster: Mapped[Rooster] = relationship(back_populates="cards") vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False) vendor: Mapped[Vendor] = relationship(back_populates="cards")