from typing import TYPE_CHECKING, Optional from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship, Mapped, mapped_column from models.base import BaseModel if TYPE_CHECKING: from models import Client, BarcodeTemplate, WildberriesProduct, OzonProduct class Product(BaseModel): __tablename__ = 'products' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(nullable=False, index=True) article: Mapped[str] = mapped_column(nullable=False, default='', server_default='', index=True) factory_article: Mapped[str] = mapped_column(nullable=False, default='', server_default='', index=True) client_id: Mapped[int] = mapped_column(ForeignKey('clients.id'), nullable=False) client: Mapped['Client'] = relationship('Client', back_populates='products') barcodes: Mapped[list['ProductBarcode']] = relationship( 'ProductBarcode', back_populates='product', cascade='all, delete-orphan', ) barcode_template_id: Mapped[Optional[int]] = mapped_column(ForeignKey('barcode_templates.id'), nullable=True) barcode_template: Mapped['BarcodeTemplate'] = relationship('BarcodeTemplate', lazy='joined') barcode_image: Mapped['ProductBarcodeImage'] = relationship( 'ProductBarcodeImage', back_populates='product', lazy='joined', uselist=False, ) # Attributes # TODO move to another table brand: Mapped[Optional[str]] = mapped_column(nullable=True, comment='Бренд') color: Mapped[Optional[str]] = mapped_column(nullable=True, comment='Цвет') composition: Mapped[Optional[str]] = mapped_column(nullable=True, comment='Состав') size: Mapped[Optional[str]] = mapped_column(nullable=True, comment='Размер') additional_info: Mapped[Optional[str]] = mapped_column(nullable=True, comment='Дополнительное поле') images: Mapped[list['ProductImage']] = relationship( 'ProductImage', back_populates='product', lazy='selectin', cascade='all, delete-orphan', ) wildberries_products: Mapped[list['WildberriesProduct']] = relationship( 'WildberriesProduct', back_populates='product', cascade='all, delete-orphan', uselist=True, ) ozon_products: Mapped[list['OzonProduct']] = relationship( 'OzonProduct', back_populates='product', cascade='all, delete-orphan', uselist=True, ) class ProductImage(BaseModel): __tablename__ = 'product_images' id: Mapped[int] = mapped_column(primary_key=True) product_id: Mapped[int] = mapped_column(ForeignKey('products.id'), nullable=False) product: Mapped['Product'] = relationship(back_populates='images') image_url: Mapped[str] = mapped_column(nullable=False) class ProductBarcode(BaseModel): __tablename__ = 'product_barcodes' product_id: Mapped[int] = mapped_column( ForeignKey('products.id'), nullable=False, comment='ID товара', primary_key=True, ) product: Mapped['Product'] = relationship(back_populates='barcodes') barcode: Mapped[str] = mapped_column(nullable=False, index=True, comment='ШК товара', primary_key=True) class ProductBarcodeImage(BaseModel): __tablename__ = 'product_barcode_images' product_id: Mapped[int] = mapped_column(ForeignKey('products.id'), primary_key=True, comment='ID товара') product: Mapped['Product'] = relationship(back_populates='barcode_image') filename: Mapped[str] = mapped_column(nullable=False)