52 lines
2.0 KiB
Python
52 lines
2.0 KiB
Python
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()]
|