"""replace embedded portfolio strategy fields with strategy references Revision ID: 20260403_0003 Revises: 20260403_0002 Create Date: 2026-04-03 01:00:00 """ from __future__ import annotations from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql revision = "20260403_0003" down_revision = "20260403_0002" branch_labels = None depends_on = None def upgrade() -> None: op.add_column("portfolios", sa.Column("active_strategy_id", sa.Text(), nullable=True)) op.add_column("portfolios", sa.Column("avabile_strategies", postgresql.ARRAY(sa.Text()), nullable=True)) op.execute( sa.text( """ UPDATE portfolios SET active_strategy_id = current_strategy_set_id, avabile_strategies = CASE WHEN current_strategy_set_id IS NULL THEN NULL ELSE ARRAY[current_strategy_set_id]::text[] END """ ) ) op.drop_column("portfolios", "strategy_name") op.drop_column("portfolios", "strategy_params") op.drop_column("portfolios", "current_strategy_set_id") def downgrade() -> None: op.add_column("portfolios", sa.Column("strategy_name", sa.Text(), nullable=False, server_default="")) op.add_column( "portfolios", sa.Column( "strategy_params", postgresql.JSONB(astext_type=sa.Text()), nullable=False, server_default=sa.text("'{}'::jsonb"), ), ) op.add_column("portfolios", sa.Column("current_strategy_set_id", sa.Text(), nullable=True)) op.execute( sa.text( """ UPDATE portfolios p SET current_strategy_set_id = p.active_strategy_id, strategy_name = COALESCE(s.name, ''), strategy_params = CASE WHEN s.config IS NULL OR s.config = '' THEN '{}'::jsonb ELSE s.config::jsonb END FROM strategy_sets s WHERE p.active_strategy_id IS NOT NULL AND s.id = p.active_strategy_id """ ) ) op.execute( sa.text( """ UPDATE portfolios SET strategy_name = COALESCE(strategy_name, ''), strategy_params = COALESCE(strategy_params, '{}'::jsonb) """ ) ) op.drop_column("portfolios", "avabile_strategies") op.drop_column("portfolios", "active_strategy_id")