Opened 8 hours ago

Last modified 7 hours ago

#35920 assigned Bug

Migrate command runs system checks regardless of the value of requires_system_checks — at Version 1

Reported by: Jacob Walls Owned by: Jacob Walls
Component: Core (Management commands) Version: 5.1
Severity: Normal Keywords: skip-checks
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Jacob Walls)

Without --skip-checks=False, the migrate command runs system checks regardless of the value of requires_system_checks, which is [] by default (itself a little misleading) but ultimately something I would like to be able to override at the project level. The fact that [] is not respected and not overridable seems like a bug, and AFAIK it's an asymmetry with other commands. (EDIT: turns out, runserver behaves in a similar way, with a comment from 17 years ago, predating migrations, explaining there is a separate mechanism from the one that became requires_system_checks that runs the system checks. I think we can improve the story here.)


  • I wrote a system check following the documented example inside Model.check().
  • I did this as part of a feature adding a new column to my model, and I queried this column in my check. I made the necessary migration.
  • During manage.py migrate my check ran before my column was added, raising ProgrammingError.
  • I verified --skip-checks works like a charm, but I don't want to impose cryptic failures on my fellow developers who expect plain migrate to work.
  • I attempted to override the migrate command in my project, like this:

/app/management/commands/migrate.py

from django.core.checks.registry import registry
from django.core.management.commands.migrate import Command as MigrateCommand


class Command(MigrateCommand):
    # Silence model checks that may depend on new columns.
    requires_system_checks = list(registry.tags_available() - {"models"})
  • Result: no change: ProgrammingError
  • Then, I added this patch to Django. (--skip-checks still works; here, I have to avoid it being added again):
    • django/core/management/commands/migrate.py

      diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py
      index fa420ee6e3..4000d76f3b 100644
      a b class Command(BaseCommand):  
      1919    help = (
      2020        "Updates database schema. Manages both apps with migrations and those without."
      2121    )
      22     requires_system_checks = []
       22    requires_system_checks = "__all__"
      2323
      2424    def add_arguments(self, parser):
      25         parser.add_argument(
      26             "--skip-checks",
      27             action="store_true",
      28             help="Skip system checks.",
      29         )
      3025        parser.add_argument(
      3126            "app_label",
      3227            nargs="?",
      class Command(BaseCommand):  
      9994    def handle(self, *args, **options):
      10095        database = options["database"]
      10196        if not options["skip_checks"]:
      102             self.check(databases=[database])
       97            self.check(tags=self.requires_system_checks, databases=[database])
      10398
      10499        self.verbosity = options["verbosity"]
      105100        self.interactive = options["interactive"]
  • Result: check skipped as expected via my project-level override of the migrate command.

I suppose there's another question here about whether Tags.models checks should run as part of the migrate command, or whether the change I made at the project level should be pulled into core, given that this is a reasonably realistic scenario for development? I can take that to the forum later. But at the moment, I'm just hoping to get the override working. Happy to PR this if welcome :-)

Change History (1)

comment:1 by Jacob Walls, 7 hours ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top