from typing import Optional from sqlalchemy import ForeignKey, Text, Index from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import TSVECTOR from db.base import Base class Category(Base): __tablename__ = "categories" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) name: Mapped[Optional[str]] = mapped_column(Text) parent_id: Mapped[Optional[int]] = mapped_column(ForeignKey("categories.id")) parent: Mapped["Category"] = relationship("Category", remote_side=[id]) class Product(Base): __tablename__ = "products" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) category_id: Mapped[Optional[int]] = mapped_column(ForeignKey("categories.id")) name: Mapped[Optional[str]] = mapped_column(Text) description: Mapped[Optional[str]] = mapped_column(Text) search_vector: Mapped[str] = mapped_column(TSVECTOR) __table_args__ = ( Index("idx_products_search", "search_vector", postgresql_using="gin"), )