"""Add ondelete to transitive FK constraints. Without these, deleting a user would fail because the DB-level CASCADE only reaches first-level children (calendars, projects, people, locations). Second-level children (calendar_events via calendar_id, project_tasks via project_id, etc.) need their own ondelete rules to allow the full cascade. FK changes: calendar_events.calendar_id → CASCADE (events die with calendar) calendar_events.location_id → SET NULL (optional ref, just unlink) project_tasks.project_id → CASCADE (tasks die with project) project_tasks.person_id → SET NULL (optional assignee, just unlink) todos.project_id → SET NULL (optional ref, just unlink) Revision ID: 036 Revises: 035 Create Date: 2026-02-27 """ from alembic import op revision = "036" down_revision = "035" branch_labels = None depends_on = None def upgrade() -> None: # calendar_events.calendar_id → CASCADE op.drop_constraint( "fk_calendar_events_calendar_id", "calendar_events", type_="foreignkey" ) op.create_foreign_key( "fk_calendar_events_calendar_id", "calendar_events", "calendars", ["calendar_id"], ["id"], ondelete="CASCADE", ) # calendar_events.location_id → SET NULL op.drop_constraint( "calendar_events_location_id_fkey", "calendar_events", type_="foreignkey" ) op.create_foreign_key( "calendar_events_location_id_fkey", "calendar_events", "locations", ["location_id"], ["id"], ondelete="SET NULL", ) # project_tasks.project_id → CASCADE op.drop_constraint( "project_tasks_project_id_fkey", "project_tasks", type_="foreignkey" ) op.create_foreign_key( "project_tasks_project_id_fkey", "project_tasks", "projects", ["project_id"], ["id"], ondelete="CASCADE", ) # project_tasks.person_id → SET NULL op.drop_constraint( "project_tasks_person_id_fkey", "project_tasks", type_="foreignkey" ) op.create_foreign_key( "project_tasks_person_id_fkey", "project_tasks", "people", ["person_id"], ["id"], ondelete="SET NULL", ) # todos.project_id → SET NULL op.drop_constraint( "todos_project_id_fkey", "todos", type_="foreignkey" ) op.create_foreign_key( "todos_project_id_fkey", "todos", "projects", ["project_id"], ["id"], ondelete="SET NULL", ) def downgrade() -> None: # Reverse: remove ondelete by re-creating without it for table, col, ref_table, constraint in [ ("todos", "project_id", "projects", "todos_project_id_fkey"), ("project_tasks", "person_id", "people", "project_tasks_person_id_fkey"), ("project_tasks", "project_id", "projects", "project_tasks_project_id_fkey"), ("calendar_events", "location_id", "locations", "calendar_events_location_id_fkey"), ("calendar_events", "calendar_id", "calendars", "fk_calendar_events_calendar_id"), ]: op.drop_constraint(constraint, table, type_="foreignkey") op.create_foreign_key(constraint, table, ref_table, [col], ["id"])