"""add account_id to maintenance_schedules Revision ID: 7f136778f5a8 Revises: 8aac5b372402 Create Date: 2026-04-09 00:00:00.000000 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = '7f136778f5a8' down_revision: Union[str, None] = '8aac5b372402' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.add_column('maintenance_schedules', sa.Column('account_id', sa.UUID(), nullable=True)) op.create_foreign_key( 'fk_maintenance_schedules_account_id', 'maintenance_schedules', 'accounts', ['account_id'], ['id'], ondelete='CASCADE', ) # Primary: tree_id → trees.account_id (only where tree.account_id is NOT NULL) op.execute(""" UPDATE maintenance_schedules ms SET account_id = t.account_id FROM trees t WHERE ms.tree_id = t.id AND t.account_id IS NOT NULL AND ms.account_id IS NULL """) # Fallback: created_by → users.account_id (for is_default trees with NULL account_id) op.execute(""" UPDATE maintenance_schedules ms SET account_id = u.account_id FROM users u WHERE ms.created_by = u.id AND u.account_id IS NOT NULL AND ms.account_id IS NULL """) result = op.get_bind().execute( sa.text("SELECT COUNT(*) FROM maintenance_schedules WHERE account_id IS NULL") ) count = result.scalar() if count > 0: raise RuntimeError( f"ROLLBACK: {count} maintenance_schedules rows have NULL account_id. " "Check if created_by is NULL — those rows need manual resolution." ) op.alter_column('maintenance_schedules', 'account_id', nullable=False) op.create_index('ix_maintenance_schedules_account_id', 'maintenance_schedules', ['account_id']) def downgrade() -> None: op.drop_index('ix_maintenance_schedules_account_id', table_name='maintenance_schedules') op.drop_constraint('fk_maintenance_schedules_account_id', 'maintenance_schedules', type_='foreignkey') op.drop_column('maintenance_schedules', 'account_id')