diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2014-05-07 14:28:34 -0700 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2014-05-07 14:28:34 -0700 |
| commit | 5a917cfef319df33ca30a3b27bd0b0533b8e63bb (patch) | |
| tree | 867d316127e3bbf11fb114c6ba8910d611832974 /django | |
| parent | e9a456d11b5b63389b466ed435ef3915f0e79e4c (diff) | |
Fixed #22496: Data migrations get transactions again!
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/migrations/migration.py | 17 | ||||
| -rw-r--r-- | django/db/migrations/operations/base.py | 4 | ||||
| -rw-r--r-- | django/db/migrations/operations/special.py | 3 |
3 files changed, 21 insertions, 3 deletions
diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py index 3d7f47f0fa..708de5393d 100644 --- a/django/db/migrations/migration.py +++ b/django/db/migrations/migration.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals +from django.db.transaction import atomic class Migration(object): @@ -97,7 +98,13 @@ class Migration(object): new_state = project_state.clone() operation.state_forwards(self.app_label, new_state) # Run the operation - operation.database_forwards(self.app_label, schema_editor, project_state, new_state) + if not schema_editor.connection.features.can_rollback_ddl and operation.atomic: + # We're forcing a transaction on a non-transactional-DDL backend + with atomic(schema_editor.connection.alias): + operation.database_forwards(self.app_label, schema_editor, project_state, new_state) + else: + # Normal behaviour + operation.database_forwards(self.app_label, schema_editor, project_state, new_state) # Switch states project_state = new_state return project_state @@ -129,7 +136,13 @@ class Migration(object): # Now run them in reverse to_run.reverse() for operation, to_state, from_state in to_run: - operation.database_backwards(self.app_label, schema_editor, from_state, to_state) + if not schema_editor.connection.features.can_rollback_ddl and operation.atomic: + # We're forcing a transaction on a non-transactional-DDL backend + with atomic(schema_editor.connection.alias): + operation.database_backwards(self.app_label, schema_editor, from_state, to_state) + else: + # Normal behaviour + operation.database_backwards(self.app_label, schema_editor, from_state, to_state) return project_state diff --git a/django/db/migrations/operations/base.py b/django/db/migrations/operations/base.py index 7e93fb7836..d0ab0a39ad 100644 --- a/django/db/migrations/operations/base.py +++ b/django/db/migrations/operations/base.py @@ -24,6 +24,10 @@ class Operation(object): # Can this migration be represented as SQL? (things like RunPython cannot) reduces_to_sql = True + # Should this operation be forced as atomic even on backends with no + # DDL transaction support (i.e., does it have no DDL, like RunPython) + atomic = False + serialization_expand_args = [] def __new__(cls, *args, **kwargs): diff --git a/django/db/migrations/operations/special.py b/django/db/migrations/operations/special.py index a80096cb32..b7ffbbbd29 100644 --- a/django/db/migrations/operations/special.py +++ b/django/db/migrations/operations/special.py @@ -86,7 +86,8 @@ class RunPython(Operation): reduces_to_sql = False - def __init__(self, code, reverse_code=None): + def __init__(self, code, reverse_code=None, atomic=True): + self.atomic = atomic # Forwards code if not callable(code): raise ValueError("RunPython must be supplied with a callable") |
