from __future__ import annotations from collections.abc import Sequence from typing import Any from sqlalchemy import insert, select from sqlalchemy.ext.asyncio import AsyncSession from app.db.models import Currency, Operation, OperationType, Portfolio, Security class OperationRepository: def __init__(self, session: AsyncSession) -> None: self.session = session async def add_many(self, rows: Sequence[dict[str, Any]]) -> None: """Пакетная вставка (executemany): в день размещения в файле 1000+ строк. Коммит — на вызывающей стороне, в одной транзакции с import_batch.""" if rows: await self.session.execute(insert(Operation), list(rows)) async def add(self, **values: Any) -> Operation: operation = Operation(**values) self.session.add(operation) await self.session.flush() return operation async def list_manual( self, limit: int ) -> list[tuple[Operation, str, str, str, str, str]]: """Ручные операции (без файла), новые сверху -> (операция, код типа, портфель, ISIN, краткое имя, валюта).""" result = await self.session.execute( select( Operation, OperationType.code, Portfolio.code, Security.isin, Security.name, Currency.code, ) .join(OperationType, OperationType.id == Operation.operation_type_id) .join(Portfolio, Portfolio.id == Operation.portfolio_id) .join(Security, Security.id == Operation.security_id) .join(Currency, Currency.id == Operation.currency_id) .where(Operation.import_batch_id.is_(None)) .order_by(Operation.id.desc()) .limit(limit) ) return [tuple(row) for row in result.all()]