소스 검색

Fixed #23303 -- Added BEGIN and COMMIT statements to the output of sqlmigrate.

Baptiste Mispelon 10 년 전
부모
커밋
5853c87a45

+ 10 - 2
django/core/management/commands/sqlmigrate.py

@@ -10,6 +10,8 @@ from django.db.migrations.loader import AmbiguityError
 class Command(BaseCommand):
     help = "Prints the SQL statements for the named migration."
 
+    output_transaction = True
+
     def add_arguments(self, parser):
         parser.add_argument('app_label',
             help='App label of the application containing the migration.')
@@ -21,6 +23,13 @@ class Command(BaseCommand):
         parser.add_argument('--backwards', action='store_true', dest='backwards',
             default=False, help='Creates SQL to unapply the migration, rather than to apply it')
 
+    def execute(self, *args, **options):
+        # sqlmigrate doesn't support coloring its output but we need to force
+        # no_color=True so that the BEGIN/COMMIT statements added by
+        # output_transaction don't get colored either.
+        options['no_color'] = True
+        return super(Command, self).execute(*args, **options)
+
     def handle(self, *args, **options):
         # Get the database we're operating from
         connection = connections[options['database']]
@@ -46,5 +55,4 @@ class Command(BaseCommand):
         # for it
         plan = [(executor.loader.graph.nodes[targets[0]], options['backwards'])]
         sql_statements = executor.collect_sql(plan)
-        for statement in sql_statements:
-            self.stdout.write(statement)
+        return '\n'.join(sql_statements)

+ 2 - 0
docs/intro/tutorial01.txt

@@ -480,6 +480,7 @@ readability):
 
 .. code-block:: sql
 
+    BEGIN;
     CREATE TABLE polls_question (
         "id" serial NOT NULL PRIMARY KEY,
         "question_text" varchar(200) NOT NULL,
@@ -500,6 +501,7 @@ readability):
         FOREIGN KEY ("question_id")
         REFERENCES "polls_question" ("id")
         DEFERRABLE INITIALLY DEFERRED;
+    COMMIT;
 
 
 Note the following:

+ 2 - 0
docs/ref/contrib/gis/tutorial.txt

@@ -285,6 +285,7 @@ This command should produce the following output:
 
 .. code-block:: sql
 
+    BEGIN;
     CREATE TABLE "world_worldborder" (
         "id" serial NOT NULL PRIMARY KEY,
         "name" varchar(50) NOT NULL,
@@ -302,6 +303,7 @@ This command should produce the following output:
     )
     ;
     CREATE INDEX "world_worldborder_mpoly_id" ON "world_worldborder" USING GIST ( "mpoly" );
+    COMMIT;
 
 .. note::
 

+ 2 - 0
docs/ref/django-admin.txt

@@ -1136,6 +1136,8 @@ Prints the SQL for the named migration. This requires an active database
 connection, which it will use to resolve constraint names; this means you must
 generate the SQL against a copy of the database you wish to later apply it on.
 
+Note that ``sqlmigrate`` doesn't colorize its output.
+
 The :djadminopt:`--database` option can be used to specify the database for
 which to generate the SQL.
 

+ 7 - 0
tests/migrations/test_commands.py

@@ -93,6 +93,13 @@ class MigrateTests(MigrationTestBase):
         """
         Makes sure that sqlmigrate does something.
         """
+        # Make sure the output is wrapped in a transaction
+        stdout = six.StringIO()
+        call_command("sqlmigrate", "migrations", "0001", stdout=stdout)
+        output = stdout.getvalue().lower()
+        self.assertIn("begin;", output)
+        self.assertIn("commit;", output)
+
         # Test forwards. All the databases agree on CREATE TABLE, at least.
         stdout = six.StringIO()
         call_command("sqlmigrate", "migrations", "0001", stdout=stdout)

+ 10 - 0
tests/user_commands/management/commands/transaction.py

@@ -0,0 +1,10 @@
+from django.core.management.base import BaseCommand
+
+
+class Command(BaseCommand):
+    help = "Say hello."
+    args = ''
+    output_transaction = True
+
+    def handle(self, *args, **options):
+        return 'Hello!'

+ 5 - 0
tests/user_commands/tests.py

@@ -134,6 +134,11 @@ class CommandTests(SimpleTestCase):
         with self.assertRaises(CommandError):
             management.call_command('hal', stdout=out)
 
+    def test_output_transaction(self):
+        out = StringIO()
+        management.call_command('transaction', stdout=out, no_color=True)
+        self.assertEqual(out.getvalue(), 'BEGIN;\nHello!\n\nCOMMIT;\n')
+
 
 class UtilsTests(SimpleTestCase):