--- id: 71256008-18b8-4206-a036-909fe11ce901 type: workflow title: "PR review: paper-dynasty-database#45 — batch BattingCard/BattingCardRatings lookups (APPROVED)" tags: [pr-reviewer, paper-dynasty-database, python, peewee, performance, batch-query, sqlite] importance: 0.4 confidence: 0.8 created: "2026-03-03T23:48:28.060018+00:00" updated: "2026-03-03T23:48:28.467508+00:00" relations: - target: 0fdd32ea-6b6a-4cd0-aa4b-117184e0c81d type: RELATED_TO direction: outgoing strength: 0.72 edge_id: 1c6215e6-eb13-43a6-a72e-75b334fff2fb - target: 1e0e14cd-588f-417d-8fcb-a48a6cca506d type: RELATED_TO direction: outgoing strength: 0.72 edge_id: 45f8434c-5683-4ba1-902b-b6250111bef6 - target: b9375a89-6e0f-4722-bca7-f1cd655de81a type: RELATED_TO direction: outgoing strength: 0.72 edge_id: ef594550-29a0-4130-aceb-ef7d88ad1fae --- ## PR #45 — fix: batch BattingCard/BattingCardRatings lookups in lineup builder **Verdict:** APPROVED (could not post — Gitea blocks self-review) **Files reviewed:** `app/routers_v2/teams.py` **What the PR does:** - Before the position loop in `get_team_lineup`, batch-fetches all `BattingCard` rows for `legal_players ∪ backup_players` in one query - Batch-fetches all `BattingCardRatings` for those cards in a second query - Builds `_batting_cards_by_player` (player_id → BattingCard) and `_ratings_by_card_hand` (card_id → {hand → BattingCardRatings}) dicts - Rewrites `get_bratings()` closure to do O(1) dict lookups instead of 3 DB queries per player **Key correctness checks:** - Dict keys match: `battingcard_id` (FK integer) in ratings dict == `this_bcard.id` in lookup - Error behaviour preserved: missing card/ratings still raises AttributeError (caught by callers) - Empty guard: `if _batting_cards_by_player else []` prevents empty IN clause - Passing BattingCard model instances to Peewee `<<` is valid; PK extraction is automatic **Pre-existing issues noted (out of scope):** - Dead code block lines 544-576 (old batch approach, commented out) - `get_bratings()` call at line 537 not wrapped in try/except