edh-elo/app/routers/score.py
2024-08-07 22:26:39 -07:00

50 lines
1.6 KiB
Python

from fastapi import APIRouter, Depends
from sqlalchemy.sql.expression import func
from ..sql import crud, models, schemas
from ..sql.database import get_db
api_router = APIRouter(prefix="/score", tags=["score"])
@api_router.get("/{deck_id}/latest", response_model=schemas.EloScore)
def get_latest_score_for_deck(deck_id: int, db=Depends(get_db)):
return crud.get_latest_score_for_deck(db, deck_id)
@api_router.get("/{deck_id}/all", response_model=list[schemas.EloScore])
def get_all_scores_for_deck(deck_id: int, db=Depends(get_db)):
return crud.get_all_scores_for_deck(db, deck_id)
@api_router.get("/{deck_id}/by_date")
def get_scores_for_deck_by_date(deck_id: int, db=Depends(get_db)):
row_number_column = (
func.row_number()
.over(
partition_by=[models.Deck.name, models.Game.date],
order_by=models.EloScore.id.desc(),
)
.label("row_number")
)
sub_query = (
db.query(models.EloScore.score, models.Game.date)
.filter(models.EloScore.deck_id == deck_id)
.join(models.Game, models.EloScore.after_game_id == models.Game.id)
# Necessary because the `row_number_column` makes the Deck table involved, so we need a join to avoid full
# Cartesian join.
.join(models.Deck, models.EloScore.deck_id == models.Deck.id)
.add_column(row_number_column)
)
sub_query = sub_query.subquery()
query = db.query(sub_query).filter(sub_query.c.row_number == 1)
results = query.all()
return list(
map(
lambda x: {k: v for k, v in x._asdict().items() if k not in ["row_number"]},
results,
)
)