/
aastray
/
StudentPart
Обзор
Документация
Войти
/
aastray
/
StudentPart
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
service/src/database/models/practice_file.py
81 строка
3 KB
aastray
Реализован функционал загрузки файлов и просмотра документов, удалены базовые эндпоинты, обновлена документация
10 янв 2026, 15:38
10 янв 2026, 15:38
4d47c55
Код
Авторство
О чём код?
""" Модель для хранения ссылок на загруженные файлы. Файлы хранятся в локальном файловом хранилище, в БД хранятся только метаданные и пути к файлам. В будущем можно легко перейти на S3, заменив только путь хранения. """ from uuid import uuid4 from sqlalchemy import Column, String, DateTime, ForeignKey, JSON from sqlalchemy.dialects.postgresql import ENUM from sqlalchemy.sql import func from sqlalchemy.orm import relationship from src.database import Base from typing import TYPE_CHECKING if TYPE_CHECKING: from src.database.models.practice_application import PracticeApplication # Enum типы для PostgreSQL FileTypeEnum = ENUM( 'document_scan', # Скан документа с печатью 'report', # Отчет о практике name='filetype', create_type=False ) DocumentScanTypeEnum = ENUM( 'contract', # Договор 'assignment', # Индивидуальное задание 'instruction', # Лист учета инструктажа 'direction', # Направление name='documentscantype', create_type=False ) class PracticeApplicationFile(Base): """ Модель для хранения метаданных загруженных файлов. Сами файлы хранятся в локальном хранилище (file_storage/), в БД хранятся только пути и метаданные. """ __tablename__ = "practice_application_files" id = Column(String, primary_key=True, default=lambda: uuid4().hex) application_id = Column(String, ForeignKey('practice_applications.id', ondelete='CASCADE'), nullable=False, index=True) # Тип файла file_type = Column(FileTypeEnum, nullable=False, index=True) # Для документов: тип скана (contract, assignment, instruction, direction) # Для отчетов: None document_scan_type = Column(DocumentScanTypeEnum, nullable=True, index=True) # Путь к файлу в хранилище (относительно корня хранилища) file_path = Column(String, nullable=False) # Оригинальное имя файла original_filename = Column(String, nullable=False) # Размер файла в байтах file_size = Column(String, nullable=False) # String для больших чисел # MIME тип файла mime_type = Column(String, nullable=True) # Метаданные файла (JSON) - переименовано из metadata, т.к. metadata зарезервировано в SQLAlchemy # В БД колонка называется 'metadata', в модели - 'file_metadata' file_metadata = Column(JSON, name='metadata', nullable=True) # Временные метки created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) # Связь с анкетой (будет установлена в __init__.py) application = relationship("PracticeApplication", back_populates="files") def __repr__(self): return f"<PracticeApplicationFile(id={self.id}, file_type={self.file_type}, path={self.file_path})>"