"""rename strategy_set columns and add nick Revision ID: 20260403_0002 Revises: 20260403_0001 Create Date: 2026-04-03 00:30:00 """ from __future__ import annotations from alembic import op import sqlalchemy as sa revision = "20260403_0002" down_revision = "20260403_0001" branch_labels = None depends_on = None def _drop_unique_constraint_for_columns(table_name: str, columns: tuple[str, ...]) -> None: bind = op.get_bind() rows = bind.execute( sa.text( """ SELECT c.conname, array_agg(a.attname ORDER BY u.ord) AS column_names FROM pg_constraint c JOIN pg_class t ON t.oid = c.conrelid JOIN pg_namespace n ON n.oid = t.relnamespace JOIN unnest(c.conkey) WITH ORDINALITY AS u(attnum, ord) ON TRUE JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = u.attnum WHERE c.contype = 'u' AND n.nspname = current_schema() AND t.relname = :table_name GROUP BY c.conname """ ), {"table_name": table_name}, ) expected = list(columns) for row in rows: if list(row.column_names) == expected: op.drop_constraint(row.conname, table_name, type_="unique") return def upgrade() -> None: op.add_column("strategy_sets", sa.Column("name", sa.Text(), nullable=True)) op.add_column("strategy_sets", sa.Column("config", sa.Text(), nullable=True, server_default="")) op.add_column("strategy_sets", sa.Column("nick", sa.Text(), nullable=True)) op.execute( sa.text( """ UPDATE strategy_sets SET name = strategy_name, config = strategy_config, nick = strategy_name || ':' || substr(md5(strategy_config), 1, 12) """ ) ) op.alter_column("strategy_sets", "name", nullable=False) op.alter_column("strategy_sets", "config", nullable=False) op.alter_column("strategy_sets", "nick", nullable=False) _drop_unique_constraint_for_columns("strategy_sets", ("strategy_name", "strategy_config")) op.create_unique_constraint("uq_strategy_sets_name_config", "strategy_sets", ["name", "config"]) op.create_unique_constraint("uq_strategy_sets_nick", "strategy_sets", ["nick"]) op.drop_column("strategy_sets", "strategy_name") op.drop_column("strategy_sets", "strategy_config") def downgrade() -> None: op.add_column("strategy_sets", sa.Column("strategy_name", sa.Text(), nullable=True)) op.add_column("strategy_sets", sa.Column("strategy_config", sa.Text(), nullable=True, server_default="")) op.execute( sa.text( """ UPDATE strategy_sets SET strategy_name = name, strategy_config = config """ ) ) op.alter_column("strategy_sets", "strategy_name", nullable=False) op.alter_column("strategy_sets", "strategy_config", nullable=False) _drop_unique_constraint_for_columns("strategy_sets", ("nick",)) _drop_unique_constraint_for_columns("strategy_sets", ("name", "config")) op.create_unique_constraint("uq_strategy_sets_name_config", "strategy_sets", ["strategy_name", "strategy_config"]) op.drop_column("strategy_sets", "nick") op.drop_column("strategy_sets", "name") op.drop_column("strategy_sets", "config")