Repository: django/django
Issue category: Bug Report

Issue:
sqlmigrate prevents normal colorization of system checks
Description
	 
sqlmigrate forces no_color=True for the sake of not colorizing the sql keywords BEGIN; and COMMIT;, but this has the side effect of preventing system check output from being colorized.
(To reproduce, begin with a project that will emit a system check, and run sqlmigrate.)
Suggesting a small ​PR to preserve the non-colorization of BEGIN; and COMMIT; while still colorizing system checks.


Hints:

Patch:
diff --git a/django/core/management/commands/sqlmigrate.py b/django/core/management/commands/sqlmigrate.py
index 3e3151f0cf3c..076499b3e2cb 100644
--- a/django/core/management/commands/sqlmigrate.py
+++ b/django/core/management/commands/sqlmigrate.py
@@ -32,10 +32,9 @@ def add_arguments(self, parser):
         )
 
     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
+        # sqlmigrate doesn't support coloring its output, so make the
+        # BEGIN/COMMIT statements added by output_transaction colorless also.
+        self.style.SQL_KEYWORD = lambda noop: noop
         return super().execute(*args, **options)
 
     def handle(self, *args, **options):


Test patch:
diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py
index 724c88a28fa8..acd7ef4c4e5e 100644
--- a/tests/migrations/test_commands.py
+++ b/tests/migrations/test_commands.py
@@ -9,6 +9,7 @@
 
 from django.apps import apps
 from django.core.management import CommandError, call_command
+from django.core.management.base import SystemCheckError
 from django.core.management.commands.makemigrations import (
     Command as MakeMigrationsCommand,
 )
@@ -859,7 +860,7 @@ def test_sqlmigrate_forwards(self):
         sqlmigrate outputs forward looking SQL.
         """
         out = io.StringIO()
-        call_command("sqlmigrate", "migrations", "0001", stdout=out)
+        call_command("sqlmigrate", "migrations", "0001", stdout=out, no_color=True)
 
         lines = out.getvalue().splitlines()
 
@@ -921,7 +922,14 @@ def test_sqlmigrate_backwards(self):
         call_command("migrate", "migrations", verbosity=0)
 
         out = io.StringIO()
-        call_command("sqlmigrate", "migrations", "0001", stdout=out, backwards=True)
+        call_command(
+            "sqlmigrate",
+            "migrations",
+            "0001",
+            stdout=out,
+            backwards=True,
+            no_color=True,
+        )
 
         lines = out.getvalue().splitlines()
         try:
@@ -1098,6 +1106,30 @@ def test_sqlmigrate_unrepresentable(self):
             ],
         )
 
+    @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
+    def test_sqlmigrate_transaction_keywords_not_colorized(self):
+        out = io.StringIO()
+        with mock.patch(
+            "django.core.management.color.supports_color", lambda *args: True
+        ):
+            call_command("sqlmigrate", "migrations", "0001", stdout=out, no_color=False)
+        self.assertNotIn("\x1b", out.getvalue())
+
+    @override_settings(
+        MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_operations"},
+        INSTALLED_APPS=["django.contrib.auth"],
+    )
+    def test_sqlmigrate_system_checks_colorized(self):
+        with (
+            mock.patch(
+                "django.core.management.color.supports_color", lambda *args: True
+            ),
+            self.assertRaisesMessage(SystemCheckError, "\x1b"),
+        ):
+            call_command(
+                "sqlmigrate", "migrations", "0001", skip_checks=False, no_color=False
+            )
+
     @override_settings(
         INSTALLED_APPS=[
             "migrations.migrations_test_apps.migrated_app",