From 1b25db46c0eb3ed59704d660603a82a8ac73b2fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pave=C5=82=20Ty=C5=9Blacki?= Date: Sun, 11 Feb 2024 23:09:45 +0000 Subject: [PATCH] fix deferred sql errors --- CHANGES.md | 1 + .../backends/postgres/schema.py | 10 ++++++---- .../migrations/0004_set_field_not_null.py | 6 ++++++ tests/settings.py | 9 +++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ee2a0e5..07e3c6b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # django-pg-zero-downtime-migrations changelog ## 0.14 + - fix deferred sql errors - drop postgres 11 support - mark `migrate_isnotnull_check_constraints` command deprecated diff --git a/django_zero_downtime_migrations/backends/postgres/schema.py b/django_zero_downtime_migrations/backends/postgres/schema.py index 92745a5..92a27a1 100644 --- a/django_zero_downtime_migrations/backends/postgres/schema.py +++ b/django_zero_downtime_migrations/backends/postgres/schema.py @@ -241,6 +241,7 @@ def __init__(self, connection, collect_sql=False, atomic=True): self.FLEXIBLE_STATEMENT_TIMEOUT = getattr( settings, "ZERO_DOWNTIME_MIGRATIONS_FLEXIBLE_STATEMENT_TIMEOUT", False) self.RAISE_FOR_UNSAFE = getattr(settings, "ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE", False) + self.DEFERRED_SQL = getattr(settings, "ZERO_DOWNTIME_DEFERRED_SQL", True) def execute(self, sql, params=()): if sql is DUMMY_SQL: @@ -296,12 +297,13 @@ def _set_operation_timeout(self, statement_timeout=None, lock_timeout=None): self.execute(self.sql_set_lock_timeout % {"lock_timeout": previous_lock_timeout}) def _flush_deferred_sql(self): - """As some alternative sql use deferred sql and deferred sql run after all operations in miration module + """As some alternative sql use deferred sql and deferred sql run after all operations in migration module so good idea to run deferred sql as soon as possible to provide similar as possible state between operations in migration module.""" - for sql in self.deferred_sql: - self.execute(sql) - self.deferred_sql.clear() + if not self.DEFERRED_SQL: + for sql in self.deferred_sql: + self.execute(sql) + self.deferred_sql.clear() def create_model(self, model): super().create_model(model) diff --git a/tests/apps/good_flow_app/migrations/0004_set_field_not_null.py b/tests/apps/good_flow_app/migrations/0004_set_field_not_null.py index 5d39342..ba69069 100644 --- a/tests/apps/good_flow_app/migrations/0004_set_field_not_null.py +++ b/tests/apps/good_flow_app/migrations/0004_set_field_not_null.py @@ -3,6 +3,11 @@ from django.db import IntegrityError, migrations, models +def flush_deferred_sql(apps, schema_editor): + for sql in schema_editor.deferred_sql: + schema_editor.execute(sql) + + def update_objects(apps, schema_editor): db_alias = schema_editor.connection.alias TestTable = apps.get_model('good_flow_app', 'TestTable') @@ -37,5 +42,6 @@ class Migration(migrations.Migration): name='field', field=models.IntegerField(default=0), ), + migrations.RunPython(flush_deferred_sql, migrations.RunPython.noop), migrations.RunPython(insert_objects_and_not_null_check, migrations.RunPython.noop), ] diff --git a/tests/settings.py b/tests/settings.py index d926ae4..9b1a0ee 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -51,6 +51,15 @@ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +MIGRATION_MODULES = { + 'admin': None, + 'auth': None, + 'contenttypes': None, + 'sessions': None, + 'messages': None, + 'staticfiles': None, +} + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates',