"""Migrate player_user table to remove player_id and make user_code unique globally. Idempotent and data-preserving: the table is only rebuilt when the legacy ``player_id`` column is actually present. Existing code/name pairs are carried over into the new schema, and on a fresh or already-migrated database this script is a no-op. The rebuild uses a temporary table rather than a bare ``DROP TABLE`` so that user data is never lost. """ import sys sys.path.insert(0, '/app') from app.app import create_app from app.extensions import db from sqlalchemy import text app = create_app('production') with app.app_context(): print("Migrating player_user table...") inspector = db.inspect(db.engine) if 'player_user' not in inspector.get_table_names(): # Fresh database — just create the current schema. db.create_all() print("✓ player_user table created with current schema.") sys.exit(0) columns = [col['name'] for col in inspector.get_columns('player_user')] if 'player_id' not in columns: # Already migrated — running the migration again must not destroy data. db.create_all() print("✓ player_user table already migrated, skipping.") sys.exit(0) # Legacy schema detected: rebuild it, preserving user_code/user_name. print(" Legacy schema detected (player_id present) — rebuilding...") with db.engine.connect() as conn: conn.execute(text( 'CREATE TABLE player_user_new (' ' id INTEGER PRIMARY KEY,' ' user_code VARCHAR(255) NOT NULL UNIQUE,' ' user_name VARCHAR(255),' ' created_at DATETIME NOT NULL,' ' updated_at DATETIME NOT NULL' ')' )) # De-duplicate on user_code (the new schema makes it globally unique). conn.execute(text( 'INSERT OR IGNORE INTO player_user_new ' '(id, user_code, user_name, created_at, updated_at) ' 'SELECT id, user_code, user_name, created_at, updated_at ' 'FROM player_user ' 'WHERE user_code IS NOT NULL' )) conn.execute(text('DROP TABLE player_user')) conn.execute(text('ALTER TABLE player_user_new RENAME TO player_user')) conn.commit() print("✓ player_user table migrated successfully!") print(" - Removed player_id foreign key") print(" - Made user_code unique globally") print(" - user_name is now nullable") print(" - Existing user_code/user_name rows preserved")