fix: batch BattingCard/BattingCardRatings lookups in lineup builder (#18)
Replace per-player get_or_none() calls in get_bratings() with two bulk SELECT queries before the position loop, keyed by player_id and card+hand. This reduces DB round trips from O(3N) to O(2) for all lineup difficulties. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8227b57875
commit
62b205bde2
@ -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),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user