DRRK/app/repositories/exchange_rates.py

58 lines
1.9 KiB
Python

from __future__ import annotations
from collections.abc import Sequence
from datetime import date
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.models import ExchangeRate
from app.integrations.cbr import FxRate
from app.repositories._upsert import insert_for
class ExchangeRateRepository:
def __init__(self, session: AsyncSession) -> None:
self.session = session
async def last_rate_date(self, currency_id: int) -> date | None:
result = await self.session.execute(
select(func.max(ExchangeRate.rate_date)).where(
ExchangeRate.currency_id == currency_id
)
)
return result.scalar_one_or_none()
async def upsert_many(
self, currency_id: int, rates: Sequence[FxRate], user: str
) -> None:
for rate in rates:
stmt = insert_for(self.session, ExchangeRate.__table__).values(
currency_id=currency_id,
rate_date=rate.rate_date,
nominal=rate.nominal,
rate=rate.value,
created_by=user,
updated_by=user,
)
stmt = stmt.on_conflict_do_update(
index_elements=["currency_id", "rate_date"],
set_={
"nominal": stmt.excluded.nominal,
"rate": stmt.excluded.rate,
"loaded_at": func.now(),
"updated_at": func.now(),
"updated_by": user,
},
)
await self.session.execute(stmt)
async def list_recent(self, currency_id: int, limit: int) -> Sequence[ExchangeRate]:
result = await self.session.execute(
select(ExchangeRate)
.where(ExchangeRate.currency_id == currency_id)
.order_by(ExchangeRate.rate_date.desc())
.limit(limit)
)
return result.scalars().all()