Normalize Player.franchise to city-agnostic values

- Add SQL migration script to update all franchise values
- Change AI roster queries from Team.lname to Team.sname
- Add FRANCHISE_NORMALIZE helper for bulk imports
- Update St Louis Cardinals hardcoded fix

Enables cross-era player matching for AI rosters (fixes Oakland Athletics issue)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-01-07 12:00:45 -06:00
parent bf1601c9a0
commit 09924faea5
4 changed files with 197 additions and 6 deletions

View File

@ -18,6 +18,49 @@ from ..db_engine import db, Player, model_to_dict, fn, chunked, Paperdex, Cardse
BattingCardRatings, PitchingCard, PitchingCardRatings, CardPosition, MlbPlayer
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
# Franchise normalization: Convert city+team names to city-agnostic team names
# This enables cross-era player matching (e.g., 'Oakland Athletics' -> 'Athletics')
FRANCHISE_NORMALIZE = {
'Arizona Diamondbacks': 'Diamondbacks',
'Atlanta Braves': 'Braves',
'Baltimore Orioles': 'Orioles',
'Boston Red Sox': 'Red Sox',
'Chicago Cubs': 'Cubs',
'Chicago White Sox': 'White Sox',
'Cincinnati Reds': 'Reds',
'Cleveland Guardians': 'Guardians',
'Colorado Rockies': 'Rockies',
'Detroit Tigers': 'Tigers',
'Houston Astros': 'Astros',
'Kansas City Royals': 'Royals',
'Los Angeles Angels': 'Angels',
'Los Angeles Dodgers': 'Dodgers',
'Miami Marlins': 'Marlins',
'Milwaukee Brewers': 'Brewers',
'Minnesota Twins': 'Twins',
'New York Mets': 'Mets',
'New York Yankees': 'Yankees',
'Oakland Athletics': 'Athletics',
'Philadelphia Phillies': 'Phillies',
'Pittsburgh Pirates': 'Pirates',
'San Diego Padres': 'Padres',
'San Francisco Giants': 'Giants',
'Seattle Mariners': 'Mariners',
'St Louis Cardinals': 'Cardinals',
'St. Louis Cardinals': 'Cardinals',
'Tampa Bay Rays': 'Rays',
'Texas Rangers': 'Rangers',
'Toronto Blue Jays': 'Blue Jays',
'Washington Nationals': 'Nationals',
}
def normalize_franchise(franchise: str) -> str:
"""Convert city+team name to team-only (e.g., 'Oakland Athletics' -> 'Athletics')"""
titled = franchise.title()
return FRANCHISE_NORMALIZE.get(titled, titled)
logging.basicConfig(
filename=LOG_DATA['filename'],
format=LOG_DATA['format'],
@ -736,7 +779,7 @@ async def put_players(players: PlayerModel, token: str = Depends(oauth2_scheme))
'image': x.image,
'image2': x.image2,
'mlbclub': x.mlbclub.title(),
'franchise': x.franchise.title(),
'franchise': normalize_franchise(x.franchise),
'cardset_id': x.cardset_id,
'rarity_id': x.rarity_id,
'set_num': x.set_num,

View File

@ -258,7 +258,7 @@ async def get_team_lineup(
# all_players = Player.select().where(
# (fn.Lower(Player.p_name) != pitcher_name.lower()) & (Player.mlbclub == this_team.lname)
# )
all_players = Player.select().where(Player.franchise == this_team.lname)
all_players = Player.select().where(Player.franchise == this_team.sname)
if difficulty_name == 'exhibition':
logging.info(f'pulling an exhibition lineup')
@ -519,7 +519,7 @@ async def get_team_sp(
db.close()
raise HTTPException(status_code=400, detail=f'Difficulty name {difficulty_name} not a valid check')
all_players = Player.select().where(Player.franchise == this_team.lname)
all_players = Player.select().where(Player.franchise == this_team.sname)
if difficulty_name == 'exhibition':
logging.info(f'pulling an exhibition lineup')
@ -619,7 +619,7 @@ async def get_team_rp(
raise HTTPException(status_code=400, detail=f'Difficulty name {difficulty_name} not a valid check')
all_players = Player.select().where(
(Player.franchise == this_team.lname) & (Player.player_id.not_in(used_pitcher_ids))
(Player.franchise == this_team.sname) & (Player.player_id.not_in(used_pitcher_ids))
)
if difficulty_name == 'exhibition':

48
main.py
View File

@ -32,6 +32,50 @@ app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
DEFAULT_SEASON = 5
# Franchise normalization: Convert city+team names to city-agnostic team names
# This enables cross-era player matching (e.g., 'Oakland Athletics' -> 'Athletics')
FRANCHISE_NORMALIZE = {
'Arizona Diamondbacks': 'Diamondbacks',
'Atlanta Braves': 'Braves',
'Baltimore Orioles': 'Orioles',
'Boston Red Sox': 'Red Sox',
'Chicago Cubs': 'Cubs',
'Chicago White Sox': 'White Sox',
'Cincinnati Reds': 'Reds',
'Cleveland Guardians': 'Guardians',
'Colorado Rockies': 'Rockies',
'Detroit Tigers': 'Tigers',
'Houston Astros': 'Astros',
'Kansas City Royals': 'Royals',
'Los Angeles Angels': 'Angels',
'Los Angeles Dodgers': 'Dodgers',
'Miami Marlins': 'Marlins',
'Milwaukee Brewers': 'Brewers',
'Minnesota Twins': 'Twins',
'New York Mets': 'Mets',
'New York Yankees': 'Yankees',
'Oakland Athletics': 'Athletics',
'Philadelphia Phillies': 'Phillies',
'Pittsburgh Pirates': 'Pirates',
'San Diego Padres': 'Padres',
'San Francisco Giants': 'Giants',
'Seattle Mariners': 'Mariners',
'St Louis Cardinals': 'Cardinals',
'St. Louis Cardinals': 'Cardinals',
'Tampa Bay Rays': 'Rays',
'Texas Rangers': 'Rangers',
'Toronto Blue Jays': 'Blue Jays',
'Washington Nationals': 'Nationals',
}
def normalize_franchise(franchise: str) -> str:
"""Convert city+team name to team-only (e.g., 'Oakland Athletics' -> 'Athletics')"""
titled = franchise.title()
return FRANCHISE_NORMALIZE.get(titled, titled)
SHEETS_AUTH = pygsheets.authorize(service_file='storage/paper-dynasty-service-creds.json', retries=1)
@ -1623,7 +1667,7 @@ async def v1_players_put(players: PlayerModel, token: str = Depends(oauth2_schem
'image': x.image,
'image2': x.image2,
'mlbclub': x.mlbclub.title(),
'franchise': x.franchise.title(),
'franchise': normalize_franchise(x.franchise),
'cardset_id': x.cardset_id,
'rarity_id': x.rarity_id,
'set_num': x.set_num,
@ -5109,7 +5153,7 @@ async def v1_stl_fix(token: str = Depends(oauth2_scheme)):
detail='You are not authorized to post. This event has been logged.'
)
p_query = Player.update(mlbclub='St Louis Cardinals', franchise='St Louis Cardinals').where(
p_query = Player.update(mlbclub='St Louis Cardinals', franchise='Cardinals').where(
Player.mlbclub == 'St. Louis Cardinals'
).execute()
db.close()

View File

@ -0,0 +1,104 @@
-- Migration: Normalize Player.franchise to city-agnostic values
-- Date: 2026-01-07
-- Purpose: Enable cross-era player matching for AI rosters by normalizing
-- franchise values to match Team.sname (e.g., 'Oakland Athletics' -> 'Athletics')
--
-- IMPORTANT: Backup database before running!
-- Run on dev first, verify with: SELECT DISTINCT franchise FROM player ORDER BY franchise;
-- Then run on prod.
--
-- Rollback: See inverse statements at bottom of file
-- ============================================
-- FORWARD MIGRATION: Normalize franchise values
-- ============================================
-- National League West
UPDATE player SET franchise = 'Diamondbacks' WHERE franchise = 'Arizona Diamondbacks';
UPDATE player SET franchise = 'Rockies' WHERE franchise = 'Colorado Rockies';
UPDATE player SET franchise = 'Dodgers' WHERE franchise = 'Los Angeles Dodgers';
UPDATE player SET franchise = 'Padres' WHERE franchise = 'San Diego Padres';
UPDATE player SET franchise = 'Giants' WHERE franchise = 'San Francisco Giants';
-- National League Central
UPDATE player SET franchise = 'Cubs' WHERE franchise = 'Chicago Cubs';
UPDATE player SET franchise = 'Reds' WHERE franchise = 'Cincinnati Reds';
UPDATE player SET franchise = 'Brewers' WHERE franchise = 'Milwaukee Brewers';
UPDATE player SET franchise = 'Pirates' WHERE franchise = 'Pittsburgh Pirates';
UPDATE player SET franchise = 'Cardinals' WHERE franchise IN ('St Louis Cardinals', 'St. Louis Cardinals');
-- National League East
UPDATE player SET franchise = 'Braves' WHERE franchise = 'Atlanta Braves';
UPDATE player SET franchise = 'Marlins' WHERE franchise = 'Miami Marlins';
UPDATE player SET franchise = 'Mets' WHERE franchise = 'New York Mets';
UPDATE player SET franchise = 'Phillies' WHERE franchise = 'Philadelphia Phillies';
UPDATE player SET franchise = 'Nationals' WHERE franchise = 'Washington Nationals';
-- American League West
UPDATE player SET franchise = 'Astros' WHERE franchise = 'Houston Astros';
UPDATE player SET franchise = 'Angels' WHERE franchise = 'Los Angeles Angels';
UPDATE player SET franchise = 'Athletics' WHERE franchise = 'Oakland Athletics';
UPDATE player SET franchise = 'Mariners' WHERE franchise = 'Seattle Mariners';
UPDATE player SET franchise = 'Rangers' WHERE franchise = 'Texas Rangers';
-- American League Central
UPDATE player SET franchise = 'White Sox' WHERE franchise = 'Chicago White Sox';
UPDATE player SET franchise = 'Guardians' WHERE franchise = 'Cleveland Guardians';
UPDATE player SET franchise = 'Tigers' WHERE franchise = 'Detroit Tigers';
UPDATE player SET franchise = 'Royals' WHERE franchise = 'Kansas City Royals';
UPDATE player SET franchise = 'Twins' WHERE franchise = 'Minnesota Twins';
-- American League East
UPDATE player SET franchise = 'Orioles' WHERE franchise = 'Baltimore Orioles';
UPDATE player SET franchise = 'Red Sox' WHERE franchise = 'Boston Red Sox';
UPDATE player SET franchise = 'Yankees' WHERE franchise = 'New York Yankees';
UPDATE player SET franchise = 'Rays' WHERE franchise = 'Tampa Bay Rays';
UPDATE player SET franchise = 'Blue Jays' WHERE franchise = 'Toronto Blue Jays';
-- ============================================
-- VERIFICATION QUERY
-- ============================================
-- Run after migration to verify all 30 teams have correct values:
-- SELECT DISTINCT franchise FROM player ORDER BY franchise;
--
-- Expected output (30 city-agnostic franchise names):
-- Angels, Athletics, Blue Jays, Braves, Brewers, Cardinals, Cubs,
-- Diamondbacks, Dodgers, Giants, Guardians, Mariners, Marlins, Mets,
-- Nationals, Orioles, Padres, Phillies, Pirates, Rangers, Rays,
-- Red Sox, Reds, Rockies, Royals, Tigers, Twins, White Sox, Yankees
-- ============================================
-- ROLLBACK MIGRATION (if needed)
-- ============================================
-- Use these statements to revert to original values:
--
-- UPDATE player SET franchise = 'Arizona Diamondbacks' WHERE franchise = 'Diamondbacks' AND mlbclub LIKE '%Arizona%';
-- UPDATE player SET franchise = 'Atlanta Braves' WHERE franchise = 'Braves' AND mlbclub LIKE '%Atlanta%';
-- UPDATE player SET franchise = 'Baltimore Orioles' WHERE franchise = 'Orioles' AND mlbclub LIKE '%Baltimore%';
-- UPDATE player SET franchise = 'Boston Red Sox' WHERE franchise = 'Red Sox' AND mlbclub LIKE '%Boston%';
-- UPDATE player SET franchise = 'Chicago Cubs' WHERE franchise = 'Cubs' AND mlbclub LIKE '%Chicago%';
-- UPDATE player SET franchise = 'Chicago White Sox' WHERE franchise = 'White Sox' AND mlbclub LIKE '%Chicago%';
-- UPDATE player SET franchise = 'Cincinnati Reds' WHERE franchise = 'Reds' AND mlbclub LIKE '%Cincinnati%';
-- UPDATE player SET franchise = 'Cleveland Guardians' WHERE franchise = 'Guardians' AND mlbclub LIKE '%Cleveland%';
-- UPDATE player SET franchise = 'Colorado Rockies' WHERE franchise = 'Rockies' AND mlbclub LIKE '%Colorado%';
-- UPDATE player SET franchise = 'Detroit Tigers' WHERE franchise = 'Tigers' AND mlbclub LIKE '%Detroit%';
-- UPDATE player SET franchise = 'Houston Astros' WHERE franchise = 'Astros' AND mlbclub LIKE '%Houston%';
-- UPDATE player SET franchise = 'Kansas City Royals' WHERE franchise = 'Royals' AND mlbclub LIKE '%Kansas%';
-- UPDATE player SET franchise = 'Los Angeles Angels' WHERE franchise = 'Angels' AND mlbclub LIKE '%Los Angeles%' AND mlbclub NOT LIKE '%Dodgers%';
-- UPDATE player SET franchise = 'Los Angeles Dodgers' WHERE franchise = 'Dodgers' AND mlbclub LIKE '%Los Angeles%';
-- UPDATE player SET franchise = 'Miami Marlins' WHERE franchise = 'Marlins' AND mlbclub LIKE '%Miami%';
-- UPDATE player SET franchise = 'Milwaukee Brewers' WHERE franchise = 'Brewers' AND mlbclub LIKE '%Milwaukee%';
-- UPDATE player SET franchise = 'Minnesota Twins' WHERE franchise = 'Twins' AND mlbclub LIKE '%Minnesota%';
-- UPDATE player SET franchise = 'New York Mets' WHERE franchise = 'Mets' AND mlbclub LIKE '%New York%';
-- UPDATE player SET franchise = 'New York Yankees' WHERE franchise = 'Yankees' AND mlbclub LIKE '%New York%';
-- UPDATE player SET franchise = 'Oakland Athletics' WHERE franchise = 'Athletics' AND mlbclub LIKE '%Oakland%';
-- UPDATE player SET franchise = 'Philadelphia Phillies' WHERE franchise = 'Phillies' AND mlbclub LIKE '%Philadelphia%';
-- UPDATE player SET franchise = 'Pittsburgh Pirates' WHERE franchise = 'Pirates' AND mlbclub LIKE '%Pittsburgh%';
-- UPDATE player SET franchise = 'San Diego Padres' WHERE franchise = 'Padres' AND mlbclub LIKE '%San Diego%';
-- UPDATE player SET franchise = 'San Francisco Giants' WHERE franchise = 'Giants' AND mlbclub LIKE '%San Francisco%';
-- UPDATE player SET franchise = 'Seattle Mariners' WHERE franchise = 'Mariners' AND mlbclub LIKE '%Seattle%';
-- UPDATE player SET franchise = 'St Louis Cardinals' WHERE franchise = 'Cardinals' AND mlbclub LIKE '%St%Louis%';
-- UPDATE player SET franchise = 'Tampa Bay Rays' WHERE franchise = 'Rays' AND mlbclub LIKE '%Tampa%';
-- UPDATE player SET franchise = 'Texas Rangers' WHERE franchise = 'Rangers' AND mlbclub LIKE '%Texas%';
-- UPDATE player SET franchise = 'Toronto Blue Jays' WHERE franchise = 'Blue Jays' AND mlbclub LIKE '%Toronto%';
-- UPDATE player SET franchise = 'Washington Nationals' WHERE franchise = 'Nationals' AND mlbclub LIKE '%Washington%';