Updated Lineup model to support both leagues using the same pattern as RosterLink: - Made card_id nullable (PD league) - Added player_id nullable (SBA league) - Added XOR CHECK constraint to ensure exactly one ID is populated - Created league-specific methods: add_pd_lineup_card() and add_sba_lineup_player() - Replaced generic create_lineup_entry() with league-specific methods Database migration applied to convert existing schema. Bonus fix: Resolved Pendulum DateTime + asyncpg timezone compatibility issue by using .naive() on all DateTime defaults in Game, Play, and GameSession models. Updated tests to use league-specific lineup methods. Archived migration docs and script to .claude/archive/ for reference. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
"""
|
|
Temporary migration script to update Lineup table schema.
|
|
|
|
This script updates the lineups table to support polymorphic card_id/player_id
|
|
structure for PD and SBA leagues.
|
|
|
|
Run this once to migrate the database schema.
|
|
|
|
Author: Claude
|
|
Date: 2025-10-23
|
|
"""
|
|
|
|
import asyncio
|
|
from sqlalchemy import text
|
|
from app.database.session import AsyncSessionLocal
|
|
|
|
|
|
async def migrate_lineup_table():
|
|
"""Update lineups table schema for polymorphic support"""
|
|
|
|
async with AsyncSessionLocal() as session:
|
|
try:
|
|
print("Starting lineup table migration...")
|
|
|
|
# Step 1: Drop existing constraint (if it exists)
|
|
print("1. Dropping existing constraints...")
|
|
await session.execute(text("""
|
|
ALTER TABLE lineups
|
|
DROP CONSTRAINT IF EXISTS lineup_one_id_required;
|
|
"""))
|
|
|
|
# Step 2: Add player_id column (nullable)
|
|
print("2. Adding player_id column...")
|
|
await session.execute(text("""
|
|
ALTER TABLE lineups
|
|
ADD COLUMN IF NOT EXISTS player_id INTEGER;
|
|
"""))
|
|
|
|
# Step 3: Make card_id nullable
|
|
print("3. Making card_id nullable...")
|
|
await session.execute(text("""
|
|
ALTER TABLE lineups
|
|
ALTER COLUMN card_id DROP NOT NULL;
|
|
"""))
|
|
|
|
# Step 4: Add CHECK constraint for XOR logic
|
|
print("4. Adding XOR constraint...")
|
|
await session.execute(text("""
|
|
ALTER TABLE lineups
|
|
ADD CONSTRAINT lineup_one_id_required
|
|
CHECK ((card_id IS NOT NULL)::int + (player_id IS NOT NULL)::int = 1);
|
|
"""))
|
|
|
|
await session.commit()
|
|
print("✓ Migration completed successfully!")
|
|
|
|
except Exception as e:
|
|
await session.rollback()
|
|
print(f"✗ Migration failed: {e}")
|
|
raise
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(migrate_lineup_table())
|