from datetime import datetime from typing import List, Optional from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy import ( Integer, String, Text, DateTime, ForeignKey, UniqueConstraint, func, ) from db.base import Base class TagGroup(Base): __tablename__ = "tag_groups" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(255), nullable=False) slug: Mapped[str] = mapped_column(String(191), unique=True, nullable=False) feature_image: Mapped[Optional[str]] = mapped_column(Text()) colour: Mapped[Optional[str]] = mapped_column(String(32)) sort_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now() ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now() ) tag_links: Mapped[List["TagGroupTag"]] = relationship( "TagGroupTag", back_populates="group", cascade="all, delete-orphan", passive_deletes=True ) class TagGroupTag(Base): __tablename__ = "tag_group_tags" __table_args__ = ( UniqueConstraint("tag_group_id", "tag_id", name="uq_tag_group_tag"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) tag_group_id: Mapped[int] = mapped_column( ForeignKey("tag_groups.id", ondelete="CASCADE"), nullable=False ) tag_id: Mapped[int] = mapped_column( ForeignKey("tags.id", ondelete="CASCADE"), nullable=False ) group: Mapped["TagGroup"] = relationship("TagGroup", back_populates="tag_links")