Skip to content

Block deleting an entity type through the Django admin

Sentry Issue: ARKINDEX-BACKEND-1EF

ForeignKeyViolation: update or delete on table "documents_entitytype" violates foreign key constraint "documents_entity_type_id_3d638b50_fk_documents_entitytype_id" on table "documents_entity"
DETAIL:  Key (id)=(70b68e24-befb-4e1e-9944-4c29c635a36c) is still referenced from table "documents_entity".

  File "django/db/backends/base/base.py", line 306, in _commit
    return self.connection.commit()

IntegrityError: update or delete on table "documents_entitytype" violates foreign key constraint "documents_entity_type_id_3d638b50_fk_documents_entitytype_id" on table "documents_entity"
DETAIL:  Key (id)=(70b68e24-befb-4e1e-9944-4c29c635a36c) is still referenced from table "documents_entity".

(15 additional frame(s) were not displayed)
...
  File "django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "django/db/backends/base/base.py", line 330, in commit
    self._commit()
  File "django/db/backends/base/base.py", line 306, in _commit
    return self.connection.commit()
  File "django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "django/db/backends/base/base.py", line 306, in _commit
    return self.connection.commit()

To make sure we cannot just bring the database down by accidentally deleting an EntityType linked to 9 billion entities, and we cannot fill the RAM by having Django fetch those 9 billion entities in RAM with the Collector class that it uses to delete related models, the Entity.type foreign key uses on_delete=models.DO_NOTHING. This causes Django to make zero checks, and we will get an IntegrityError from PostgreSQL instead, which costs little.

This however means we get an HTTP 500 from the Django admin when trying to delete an EntityType, without any warning on the confirmation page. We already have an API endpoint and a button in the frontend to delete an EntityType, and they show clean error messages when there are related entities, so either we should somehow manage to convince the Django admin to check for related entities, or we should prevent deleting altogether just like we did for corpora.