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, ) )