Skip to content

Commit

Permalink
fix deferred sql errors
Browse files Browse the repository at this point in the history
  • Loading branch information
tbicr committed Feb 12, 2024
1 parent cbfad83 commit b37b71f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
18 changes: 13 additions & 5 deletions django_zero_downtime_migrations/backends/postgres/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_MIGRATIONS_DEFERRED_SQL", True)

def execute(self, sql, params=()):
if sql is DUMMY_SQL:
Expand Down Expand Up @@ -296,12 +297,19 @@ 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()
between operations in migration module. But this approach can be reason of errors for some migrations.
As only constraints creation placed in deferred sql
it looks safe to keep standard django deferred sql run approach.
# TODO: drop option to run deferred sql as soon as possible in future
"""
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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),
]
9 changes: 9 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit b37b71f

Please sign in to comment.