import pickle from typing import TYPE_CHECKING from sqlalchemy import ForeignKey, Table, Column, UniqueConstraint, Index from sqlalchemy.orm import Mapped, mapped_column, relationship from models.base import BaseModel if TYPE_CHECKING: from models import Project, BaseModel, Card project_attribute = Table( 'project_attribute', BaseModel.metadata, Column('project_id', ForeignKey('projects.id')), Column('attribute_id', ForeignKey('attributes.id')), ) class AttributeType(BaseModel): __tablename__ = 'attribute_types' id: Mapped[int] = mapped_column(primary_key=True) type: Mapped[str] = mapped_column(nullable=False, unique=True) name: Mapped[str] = mapped_column(nullable=False, unique=True) is_deleted: Mapped[bool] = mapped_column(default=False) attributes: Mapped['Attribute'] = relationship( 'Attribute', back_populates='type', lazy='noload', ) class Attribute(BaseModel): __tablename__ = 'attributes' id: Mapped[int] = mapped_column(primary_key=True) label: Mapped[str] = mapped_column(nullable=False) name: Mapped[str] = mapped_column(nullable=False, unique=True) is_applicable_to_group: Mapped[bool] = mapped_column( default=False, comment='Применять ли изменения атрибута карточки ко всем карточкам в группе', ) is_nullable: Mapped[bool] = mapped_column(default=False, nullable=False) default_value: Mapped[bytes] = mapped_column(nullable=True) projects: Mapped[list['Project']] = relationship( 'Project', uselist=True, secondary='project_attribute', back_populates='attributes', lazy='noload', ) type_id: Mapped[int] = mapped_column(ForeignKey('attribute_types.id'), nullable=False) type: Mapped[AttributeType] = relationship( 'AttributeType', back_populates='attributes', lazy='joined', ) card_attributes: Mapped[list['CardAttribute']] = relationship( 'CardAttribute', uselist=True, lazy='noload', back_populates='attribute', ) class CardAttribute(BaseModel): __tablename__ = 'card_attributes' id: Mapped[int] = mapped_column(primary_key=True) value: Mapped[bytes] = mapped_column(nullable=True) card_id: Mapped[int] = mapped_column(ForeignKey('cards.id'), nullable=False) card: Mapped['Card'] = relationship( 'Card', back_populates='attributes', lazy='noload', ) attribute_id: Mapped[int] = mapped_column(ForeignKey('attributes.id'), nullable=False) attribute: Mapped[Attribute] = relationship( 'Attribute', back_populates='card_attributes', lazy='joined', ) __table_args__ = ( UniqueConstraint('card_id', 'attribute_id', name='uix_card_service'), Index('idx_card_id_attribute_id', 'card_id', 'attribute_id', unique=True) ) def set_value(self, value): self.value = pickle.dumps(value) def get_value(self): return pickle.loads(self.value)