"""users password_hash nullable Revision ID: 5bb055a1593e Revises: b1fad5ddf357 Create Date: 2026-05-06 07:23:21.480252 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = '5bb055a1593e' down_revision: Union[str, None] = 'b1fad5ddf357' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.alter_column( "users", "password_hash", existing_type=sa.String(255), nullable=True, ) def downgrade() -> None: # NOTE: downgrade is non-trivial if any OAuth-only users exist. # This downgrade fails fast in that case rather than corrupting data. conn = op.get_bind() null_count = conn.execute( sa.text("SELECT COUNT(*) FROM users WHERE password_hash IS NULL") ).scalar() if null_count and null_count > 0: raise RuntimeError( f"Cannot downgrade: {null_count} OAuth-only users have NULL password_hash. " "Set passwords or delete those rows before downgrading." ) op.alter_column( "users", "password_hash", existing_type=sa.String(255), nullable=False, )