87 lines
3.9 KiB
Diff
87 lines
3.9 KiB
Diff
Based on my knowledge of Django's codebase and the issue description, I can create the patch. The issue is in the `sqlmigrate` management command where `self.output_transaction` should consider both `migration.atomic` AND `connection.features.can_rollback_ddl`.
|
|
|
|
Let me provide the patch based on the Django codebase structure:
|
|
|
|
```
|
|
--- a/django/core/management/commands/sqlmigrate.py
|
|
+++ b/django/core/management/commands/sqlmigrate.py
|
|
@@ -57,7 +57,7 @@ class Command(BaseCommand):
|
|
plan = [(executor.loader.graph.nodes[targets[0]], options['backwards'])]
|
|
|
|
# Show BEGIN/COMMIT around output only for atomic migrations
|
|
- self.output_transaction = migration.atomic
|
|
+ self.output_transaction = migration.atomic and connection.features.can_rollback_ddl
|
|
|
|
# Collect output
|
|
with connection.schema_editor(collect_sql=True, atomic=migration.atomic) as schema_editor:
|
|
--- a/tests/migrations/test_commands.py
|
|
+++ b/tests/migrations/test_commands.py
|
|
@@ -1,5 +1,6 @@
|
|
import datetime
|
|
import os
|
|
+from unittest import mock
|
|
|
|
from django.apps import apps
|
|
from django.core.management import CommandError, call_command
|
|
@@ -1152,6 +1153,18 @@ class MigrateTests(MigrationTestBase):
|
|
self.assertNotIn(end_transaction_sql.lower(), output.lower())
|
|
|
|
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
|
+ def test_sqlmigrate_for_non_transactional_databases(self):
|
|
+ """
|
|
+ sqlmigrate should not wrap output in BEGIN/COMMIT if the database
|
|
+ doesn't support transactional DDL.
|
|
+ """
|
|
+ out = io.StringIO()
|
|
+ with mock.patch.object(connection.features, 'can_rollback_ddl', False):
|
|
+ call_command("sqlmigrate", "migrations", "0001", stdout=out)
|
|
+ output = out.getvalue().lower()
|
|
+ self.assertNotIn(connection.ops.start_transaction_sql().lower(), output)
|
|
+ self.assertNotIn(connection.ops.end_transaction_sql().lower(), output)
|
|
+
|
|
+ @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
|
def test_sqlmigrate_backwards(self):
|
|
"""
|
|
sqlmigrate outputs reverse migrations.
|
|
```
|
|
|
|
--- a/django/core/management/commands/sqlmigrate.py
|
|
+++ b/django/core/management/commands/sqlmigrate.py
|
|
@@ -57,7 +57,7 @@ class Command(BaseCommand):
|
|
plan = [(executor.loader.graph.nodes[targets[0]], options['backwards'])]
|
|
|
|
# Show BEGIN/COMMIT around output only for atomic migrations
|
|
- self.output_transaction = migration.atomic
|
|
+ self.output_transaction = migration.atomic and connection.features.can_rollback_ddl
|
|
|
|
# Collect output
|
|
with connection.schema_editor(collect_sql=True, atomic=migration.atomic) as schema_editor:
|
|
--- a/tests/migrations/test_commands.py
|
|
+++ b/tests/migrations/test_commands.py
|
|
@@ -1,5 +1,6 @@
|
|
import datetime
|
|
import os
|
|
+from unittest import mock
|
|
|
|
from django.apps import apps
|
|
from django.core.management import CommandError, call_command
|
|
@@ -1152,6 +1153,18 @@ class MigrateTests(MigrationTestBase):
|
|
self.assertNotIn(end_transaction_sql.lower(), output.lower())
|
|
|
|
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
|
+ def test_sqlmigrate_for_non_transactional_databases(self):
|
|
+ """
|
|
+ sqlmigrate should not wrap output in BEGIN/COMMIT if the database
|
|
+ doesn't support transactional DDL.
|
|
+ """
|
|
+ out = io.StringIO()
|
|
+ with mock.patch.object(connection.features, 'can_rollback_ddl', False):
|
|
+ call_command("sqlmigrate", "migrations", "0001", stdout=out)
|
|
+ output = out.getvalue().lower()
|
|
+ self.assertNotIn(connection.ops.start_transaction_sql().lower(), output)
|
|
+ self.assertNotIn(connection.ops.end_transaction_sql().lower(), output)
|
|
+
|
|
+ @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
|
def test_sqlmigrate_backwards(self):
|
|
"""
|
|
sqlmigrate outputs reverse migrations.
|