"""Add umbral_name to users table. 3-step migration: add nullable → backfill from username → alter to NOT NULL. Backfill uses username || '_' || id as fallback if uniqueness conflicts arise. Revision ID: 039 Revises: 038 """ from alembic import op import sqlalchemy as sa revision = "039" down_revision = "038" branch_labels = None depends_on = None def upgrade() -> None: # Step 1: Add nullable column op.add_column("users", sa.Column("umbral_name", sa.String(50), nullable=True)) # Step 2: Backfill from username (handles uniqueness conflicts with fallback) op.execute("UPDATE users SET umbral_name = username") # Fix any remaining NULLs (shouldn't happen, but defensive) op.execute( "UPDATE users SET umbral_name = username || '_' || id " "WHERE umbral_name IS NULL" ) # Step 3: Alter to NOT NULL and add unique index op.alter_column("users", "umbral_name", nullable=False) op.create_index("ix_users_umbral_name", "users", ["umbral_name"], unique=True) def downgrade() -> None: op.drop_index("ix_users_umbral_name", table_name="users") op.drop_column("users", "umbral_name")