"""Database models for YouTube feed storage.""" from datetime import datetime from typing import List from sqlalchemy import String, DateTime, ForeignKey, Index from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): """Base class for all database models.""" pass class Channel(Base): """YouTube channel model.""" __tablename__ = "channels" id: Mapped[int] = mapped_column(primary_key=True) channel_id: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, index=True) title: Mapped[str] = mapped_column(String(200), nullable=False) link: Mapped[str] = mapped_column(String(500), nullable=False) last_fetched: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow) # Relationship to video entries videos: Mapped[List["VideoEntry"]] = relationship("VideoEntry", back_populates="channel", cascade="all, delete-orphan") def __repr__(self) -> str: return f"" class VideoEntry(Base): """YouTube video entry model.""" __tablename__ = "video_entries" id: Mapped[int] = mapped_column(primary_key=True) channel_id: Mapped[int] = mapped_column(ForeignKey("channels.id"), nullable=False) title: Mapped[str] = mapped_column(String(500), nullable=False) link: Mapped[str] = mapped_column(String(500), unique=True, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow) # Relationship to channel channel: Mapped["Channel"] = relationship("Channel", back_populates="videos") # Index for faster queries __table_args__ = ( Index('idx_channel_created', 'channel_id', 'created_at'), ) def __repr__(self) -> str: return f"" def to_dict(self) -> dict: """Convert to dictionary for API responses.""" return { "id": self.id, "title": self.title, "link": self.link, "created_at": self.created_at.isoformat() }