48 lines
2.5 KiB
Python
48 lines
2.5 KiB
Python
from __future__ import annotations
|
||
|
||
from datetime import date
|
||
|
||
from sqlalchemy import BigInteger, Date, ForeignKey, Integer, String, UniqueConstraint
|
||
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
||
from app.core.config import settings
|
||
from app.db.base import Base
|
||
from app.db.types import AuditMixin, IdMixin, JsonType, qualified
|
||
|
||
|
||
class ImportBatch(IdMixin, AuditMixin, Base):
|
||
"""Загрузка файла сделок в портфель (D19).
|
||
|
||
Защита от повтора — на уровне файла: (content_sha256, portfolio_id)
|
||
уникальны. Хэш — по нормализованным строкам (app/imports/quik.py),
|
||
поэтому пересохранённый в Excel файл с теми же данными — тоже повтор.
|
||
|
||
rows_total — непустых строк в файле; rows_loaded — загружено в этот
|
||
портфель; rows_excluded — строк без портфеля (пустой/неизвестный
|
||
комментарий, /trde), которые пользователь явно исключил. Остальное —
|
||
строки другого портфеля или уже загруженные из этого файла туда.
|
||
loaded_rows — порядковые номера загруженных строк (QuikTrade.ordinal):
|
||
по ним видно, какие строки файла не загружены никуда.
|
||
"""
|
||
|
||
__tablename__ = "import_batch"
|
||
__table_args__ = (
|
||
UniqueConstraint(
|
||
"content_sha256", "portfolio_id", name="uq_import_batch_content_portfolio"
|
||
),
|
||
{"schema": settings.DATABASE_SCHEMA} if settings.DATABASE_SCHEMA else {},
|
||
)
|
||
|
||
source: Mapped[str] = mapped_column(String(10), nullable=False)
|
||
portfolio_id: Mapped[int] = mapped_column(
|
||
BigInteger, ForeignKey(qualified("portfolio.id")), nullable=False
|
||
)
|
||
file_name: Mapped[str] = mapped_column(String(255), nullable=False)
|
||
content_sha256: Mapped[str] = mapped_column(String(64), nullable=False)
|
||
date_from: Mapped[date] = mapped_column(Date, nullable=False)
|
||
date_to: Mapped[date] = mapped_column(Date, nullable=False)
|
||
rows_total: Mapped[int] = mapped_column(Integer, nullable=False)
|
||
rows_loaded: Mapped[int] = mapped_column(Integer, nullable=False)
|
||
rows_excluded: Mapped[int] = mapped_column(Integer, nullable=False)
|
||
loaded_rows: Mapped[list[int]] = mapped_column(JsonType, nullable=False)
|