From 9bdf27bc9009f4ff97a24404a752efc03ad3555f Mon Sep 17 00:00:00 2001 From: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Mon, 4 May 2026 13:49:41 -0700 Subject: [PATCH] fix(importer): avoid guardian lru_cache poisoning; include M2M through tables in check_constraints clear_cache() inside the import transaction emptied Django's ContentType manager cache while fixture PKs were live, causing downstream ContentType lookups to repopulate guardian's separate @lru_cache(None) with fixture-PK objects. After the TestCase transaction rolled back to original PKs, guardian's lru_cache held stale fixture ContentType objects, causing MixedContentTypeError in unrelated subsequent tests. Remove clear_cache() since it was defending against a theoretical stale-cache scenario that doesn't occur in a proper same-install restore. Fix check_constraints() to explicitly include auto-created M2M through tables (populated by .set() after bulk_create) alongside the model tables, addressing the gap where join-table FK violations would have gone undetected. Co-Authored-By: Claude Sonnet 4.6 --- .../management/commands/document_importer.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/documents/management/commands/document_importer.py b/src/documents/management/commands/document_importer.py index c604f8d2d..46415b4a2 100644 --- a/src/documents/management/commands/document_importer.py +++ b/src/documents/management/commands/document_importer.py @@ -383,13 +383,19 @@ class Command(CryptMixin, PaperlessCommand): flush_all() - # Stale ContentType objects cached in Python would cause lookups - # against the freshly re-imported rows to return wrong PKs. - ContentType.objects.clear_cache() - # Verify referential integrity now that all rows are inserted, # including M2M through tables written by .set() above. - connection.check_constraints() + through_tables = { + field.remote_field.through._meta.db_table + for model in loaded_models + for field in model._meta.many_to_many + if field.remote_field.through._meta.auto_created + } + table_names = [m._meta.db_table for m in loaded_models] + list( + through_tables, + ) + if table_names: + connection.check_constraints(table_names=table_names) # Sequences must be reset after inserting rows with explicit PKs # or the next auto-increment insert will collide with an existing PK.