diff --git a/backend/finance/migrations/0034_reportingentry_local_project.py b/backend/finance/migrations/0034_reportingentry_local_project.py index 52b61f2d..c9c7ccd0 100644 --- a/backend/finance/migrations/0034_reportingentry_local_project.py +++ b/backend/finance/migrations/0034_reportingentry_local_project.py @@ -2,6 +2,44 @@ import django.db.models.deletion from django.db import migrations, models +def rename_external_project_index(apps, schema_editor): + """Free the default index name before adding the new local project field. + + PostgreSQL keeps an index name unchanged when its column is renamed. The + old ``project_id`` index would therefore collide with the index Django + creates for the new ``project`` foreign key later in this migration. + """ + if schema_editor.connection.vendor != "postgresql": + return + + table_name = apps.get_model("finance", "ReportingEntry")._meta.db_table + old_name = schema_editor._create_index_name(table_name, ["project_id"], suffix="") + new_name = schema_editor._create_index_name( + table_name, ["external_project_id"], suffix="" + ) + quoted_old_name = schema_editor.quote_name(old_name) + quoted_new_name = schema_editor.quote_name(new_name) + schema_editor.execute( + f"ALTER INDEX IF EXISTS {quoted_old_name} RENAME TO {quoted_new_name}" + ) + + +def restore_external_project_index_name(apps, schema_editor): + if schema_editor.connection.vendor != "postgresql": + return + + table_name = apps.get_model("finance", "ReportingEntry")._meta.db_table + old_name = schema_editor._create_index_name(table_name, ["project_id"], suffix="") + new_name = schema_editor._create_index_name( + table_name, ["external_project_id"], suffix="" + ) + quoted_old_name = schema_editor.quote_name(old_name) + quoted_new_name = schema_editor.quote_name(new_name) + schema_editor.execute( + f"ALTER INDEX IF EXISTS {quoted_new_name} RENAME TO {quoted_old_name}" + ) + + def bind_existing_entries(apps, schema_editor): ReportingEntry = apps.get_model("finance", "ReportingEntry") Binding = apps.get_model("projects", "ProjectExternalBinding") @@ -31,6 +69,10 @@ class Migration(migrations.Migration): old_name="project", new_name="external_project", ), + migrations.RunPython( + rename_external_project_index, + restore_external_project_index_name, + ), migrations.AddField( model_name="reportingentry", name="project",