From 7dca0bfa6af103b76185aada3ce736b0ac1abc01 Mon Sep 17 00:00:00 2001 From: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Thu, 23 Jul 2026 10:09:28 -0700 Subject: [PATCH] Fix (#13214): split mailrule maximum_age clamp into its own migration (#13231) Avoids a Postgres error where the clamp UPDATE and the following ALTER TABLE on paperless_mail_mailrule share a transaction, but the table's FKs are deferrable, so pending trigger events block the ALTER. Also fixes a verbose_name mismatch in migration 0013. --- ...cationconfiguration_llm_request_timeout.py | 2 +- .../0001_1_clamp_mailrule_maximum_age.py | 27 +++++++++++++++++++ .../0002_optimize_integer_field_sizes.py | 12 +-------- 3 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 src/paperless_mail/migrations/0001_1_clamp_mailrule_maximum_age.py diff --git a/src/paperless/migrations/0013_applicationconfiguration_llm_request_timeout.py b/src/paperless/migrations/0013_applicationconfiguration_llm_request_timeout.py index 836c0696c..598928605 100644 --- a/src/paperless/migrations/0013_applicationconfiguration_llm_request_timeout.py +++ b/src/paperless/migrations/0013_applicationconfiguration_llm_request_timeout.py @@ -17,7 +17,7 @@ class Migration(migrations.Migration): field=models.PositiveSmallIntegerField( null=True, validators=[django.core.validators.MinValueValidator(1)], - verbose_name="Sets the LLM request timeout in seconds", + verbose_name="Sets the LLM timeout in seconds", ), ), ] diff --git a/src/paperless_mail/migrations/0001_1_clamp_mailrule_maximum_age.py b/src/paperless_mail/migrations/0001_1_clamp_mailrule_maximum_age.py new file mode 100644 index 000000000..4b195b746 --- /dev/null +++ b/src/paperless_mail/migrations/0001_1_clamp_mailrule_maximum_age.py @@ -0,0 +1,27 @@ +# Split out of 0002_optimize_integer_field_sizes.py into its own migration +# (own transaction). Running this UPDATE in the same transaction as the +# later ALTER TABLE on paperless_mail_mailrule can fail on PostgreSQL with +# "cannot ALTER TABLE because it has pending trigger events", since the +# update queues FK trigger events against that table that are still pending +# when the subsequent AlterField tries to rewrite it. Committing the clamp +# here first avoids that. +from django.db import migrations + + +def clamp_mailrule_maximum_age(apps, schema_editor): + # Clamp the maximum_age field of MailRule because of PositiveIntegerField --> PositiveSmallIntegerField + MailRule = apps.get_model("paperless_mail", "MailRule") + MailRule.objects.filter(maximum_age__gt=32767).update(maximum_age=32767) + + +class Migration(migrations.Migration): + dependencies = [ + ("paperless_mail", "0001_squashed"), + ] + + operations = [ + migrations.RunPython( + clamp_mailrule_maximum_age, + migrations.RunPython.noop, + ), + ] diff --git a/src/paperless_mail/migrations/0002_optimize_integer_field_sizes.py b/src/paperless_mail/migrations/0002_optimize_integer_field_sizes.py index ac8c52d3e..f42dafe36 100644 --- a/src/paperless_mail/migrations/0002_optimize_integer_field_sizes.py +++ b/src/paperless_mail/migrations/0002_optimize_integer_field_sizes.py @@ -4,15 +4,9 @@ from django.db import migrations from django.db import models -def clamp_mailrule_maximum_age(apps, schema_editor): - # Clamp the maximum_age field of MailRule because of PositiveIntegerField --> PositiveSmallIntegerField - MailRule = apps.get_model("paperless_mail", "MailRule") - MailRule.objects.filter(maximum_age__gt=32767).update(maximum_age=32767) - - class Migration(migrations.Migration): dependencies = [ - ("paperless_mail", "0001_squashed"), + ("paperless_mail", "0001_1_clamp_mailrule_maximum_age"), ] operations = [ @@ -118,10 +112,6 @@ class Migration(migrations.Migration): verbose_name="consumption scope", ), ), - migrations.RunPython( - clamp_mailrule_maximum_age, - migrations.RunPython.noop, - ), migrations.AlterField( model_name="mailrule", name="maximum_age",