@@ -73,7 +73,27 @@ class Migration(migrations.Migration):
7373 "unique_together" : {("name" , "infrastructure_type" )},
7474 },
7575 ),
76- # Step 2: Add new FK fields to Engagement (before removing old ones)
76+ # Step 2: Remove old pgtrigger triggers FIRST.
77+ # The triggers reference the old column names (build_server_id, etc.). If we left
78+ # them in place, the data migration (Step 4) would still fire AFTER UPDATE on each
79+ # engagement.save() and write rows to dojo_engagementevent that record the old
80+ # columns (untouched, so they look like no-op updates) while missing the actual
81+ # change to the new cicd_* columns — misleading audit history. Dropping the old
82+ # triggers up front skips that noise; the new triggers are re-added at Step 7
83+ # once the column renames are in place.
84+ pgtrigger .migrations .RemoveTrigger (
85+ model_name = 'engagement' ,
86+ name = 'insert_insert' ,
87+ ),
88+ pgtrigger .migrations .RemoveTrigger (
89+ model_name = 'engagement' ,
90+ name = 'update_update' ,
91+ ),
92+ pgtrigger .migrations .RemoveTrigger (
93+ model_name = 'engagement' ,
94+ name = 'delete_delete' ,
95+ ),
96+ # Step 3: Add new FK fields to Engagement (before removing old ones)
7797 migrations .AddField (
7898 model_name = "engagement" ,
7999 name = "cicd_scm_server" ,
@@ -113,23 +133,18 @@ class Migration(migrations.Migration):
113133 verbose_name = "Orchestration Engine" ,
114134 ),
115135 ),
116- # Step 3 : Migrate data from Tool_Configuration to CICDInfrastructure
136+ # Step 4 : Migrate data from Tool_Configuration to CICDInfrastructure
117137 migrations .RunPython (
118138 migrate_tool_configs_to_cicd_infrastructure ,
119139 reverse_code = migrations .RunPython .noop ,
120140 ),
121- # Step 4: Remove old pgtrigger triggers (they reference old column names)
122- pgtrigger .migrations .RemoveTrigger (
123- model_name = 'engagement' ,
124- name = 'insert_insert' ,
125- ),
126- pgtrigger .migrations .RemoveTrigger (
127- model_name = 'engagement' ,
128- name = 'update_update' ,
129- ),
130- pgtrigger .migrations .RemoveTrigger (
131- model_name = 'engagement' ,
132- name = 'delete_delete' ,
141+ # Step 4a: Force deferred FK constraint checks to fire now. Django creates FKs as
142+ # DEFERRABLE INITIALLY DEFERRED, so each engagement.save() in Step 4 queued a
143+ # constraint check for commit time. Without flushing those, the next ALTER TABLE
144+ # on dojo_engagement (Step 5) trips Postgres' "pending trigger events" guard.
145+ migrations .RunSQL (
146+ sql = "SET CONSTRAINTS ALL IMMEDIATE" ,
147+ reverse_sql = migrations .RunSQL .noop ,
133148 ),
134149 # Step 5: Remove old FK fields from Engagement
135150 migrations .RemoveField (
0 commit comments