fix: batch BattingCard/BattingCardRatings lookups in lineup builder (#18) #45

Merged
cal merged 1 commits from ai/paper-dynasty-database#18 into next-release 2026-03-07 03:16:13 +00:00

View File

@ -354,17 +354,35 @@ async def get_team_lineup(
"DH": {"player": None, "vl": None, "vr": None, "ops": 0},
}
# Batch-fetch BattingCards and ratings for all candidate players to avoid
# per-player DB round trips inside the lineup construction loop below.
if backup_players is not None:
_batch_bcards = BattingCard.select().where(
(BattingCard.player << legal_players)
| (BattingCard.player << backup_players)
)
else:
_batch_bcards = BattingCard.select().where(BattingCard.player << legal_players)
_batting_cards_by_player = {bc.player_id: bc for bc in _batch_bcards}
_all_bratings = (
BattingCardRatings.select().where(
BattingCardRatings.battingcard << list(_batting_cards_by_player.values())
)
if _batting_cards_by_player
else []
)
_ratings_by_card_hand = {}
for _r in _all_bratings:
_ratings_by_card_hand.setdefault(_r.battingcard_id, {})[_r.vs_hand] = _r
def get_bratings(player_id):
this_bcard = BattingCard.get_or_none(BattingCard.player_id == player_id)
vl_ratings = BattingCardRatings.get_or_none(
BattingCardRatings.battingcard == this_bcard,
BattingCardRatings.vs_hand == "L",
this_bcard = _batting_cards_by_player.get(player_id)
card_ratings = (
_ratings_by_card_hand.get(this_bcard.id, {}) if this_bcard else {}
)
vl_ratings = card_ratings.get("L")
vr_ratings = card_ratings.get("R")
vl_ops = vl_ratings.obp + vl_ratings.slg
vr_ratings = BattingCardRatings.get_or_none(
BattingCardRatings.battingcard == this_bcard,
BattingCardRatings.vs_hand == "R",
)
vr_ops = vr_ratings.obp + vr_ratings.slg
return (
model_to_dict(vl_ratings),