-- 039_requisition_department_id.sql -- Many requisitions -> one department. Adds requisitions.department_id, the FK -- behind Requisition.department_id / Requisition.department and -- Department.requisitions (backend/candidate_forms/models.py, -- backend/department/models.py). -- -- A new file, not an edit to 020 or 038: manual migrations run once and are -- recorded in manual_migrations, so changes to an applied file never reach an -- existing database. Applied at startup by alembic_setup.run_manual_sql() -- after 038, so app.departments already exists. -- -- The legacy free-text requisitions.department column is kept and only read -- here to backfill: rows whose text equals a department's name or short code -- (case-insensitive, trimmed) get that department's id. Unmatched rows stay -- NULL. Drop the text column in a later migration once nothing reads it. ALTER TABLE app.requisitions ADD COLUMN IF NOT EXISTS department_id uuid; DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'fk_requisitions_department_id_departments' ) THEN ALTER TABLE app.requisitions ADD CONSTRAINT fk_requisitions_department_id_departments FOREIGN KEY (department_id) REFERENCES app.departments (id); END IF; END $$; CREATE INDEX IF NOT EXISTS ix_requisitions_department_id ON app.requisitions (department_id); -- Backfill from the legacy text column, if it is still there. DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'app' AND table_name = 'requisitions' AND column_name = 'department' ) THEN UPDATE app.requisitions r SET department_id = d.id FROM app.departments d WHERE r.department_id IS NULL AND lower(btrim(r.department)) IN (lower(d.name), lower(d.short_code)); END IF; END $$;