Skip to content

Fix: Migration Autodetector class mismatch errors with dynamic command inheritance#1

Merged
erdem merged 5 commits intomainfrom
misc/django-60-support
Jan 5, 2026
Merged

Fix: Migration Autodetector class mismatch errors with dynamic command inheritance#1
erdem merged 5 commits intomainfrom
misc/django-60-support

Conversation

@erdem
Copy link

@erdem erdem commented Jan 5, 2026

Before continue to read this PR description first get initial context from this public PR.

What We Tried First (in the public PR)

INSTALLED_APPS = [
    "django_linear_migrations",  # First
    "django_pgviews",             # Second
    ...
]

Why It Failed

Django loads management commands from INSTALLED_APPS in order. The first app providing a command wins, later apps with the same command are ignored.

However:

django_linear_migrations makemigrations command module overrides django_pgviews makemigrations command module. Django sees django_linear_migrations provides makemigrations first and uses that. django_pgviews command implementation never even imports or runs and PGViewsAutodetector class modification to the original command is never applied.


Our Solution

INSTALLED_APPS = [
    "django_pgviews",            # First - ensures our commands load
    "django_linear_migrations",   # Second - we'll inherit from it
    ...
]

Why This Works

  1. Changed breakcontinue: Now our lookup skips django_pgviews but continues checking apps after us in INSTALLED_APPS
  2. Finds django_linear_migrations: When we iterate through apps, we hit django_linear_migrations (after us) and successfully import its command class
  3. Inheritance chain: Our command inherits from django_linear_migrations's command, which inherits from Django's, preserving both:
    • PGViewsAutodetector (from us)
    • max_migration.txt tracking (from django-linear-migrations)

The Risk

Normally, apps later in INSTALLED_APPS override earlier ones. With django_linear_migrations after django_pgviews, if django_linear_migrations provided both makemigrations and migrate commands, it would override ours completely and break pgviews.

Why It's Safe

django_linear_migrations only provides makemigrations command (not migrate). Since Django's command loading sees our commands are already loaded and django_linear_migrations doesn't override all of them, our commands remain active while successfully inheriting from theirs.


The Comment Explains It

# Must follow django_pgviews: pgviews dynamically inherits from commands loaded
# before it, preserving both PGViewsAutodetector + max_migration.txt tracking

We're essentially saying: "Load us first so we control the final commands, but we'll look ahead and inherit from apps that come after us."

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

Coverage

Coverage Report •
FileStmtsMissCoverMissing
django_pgviews/management/commands
   makemigrations.py16160%1, 3–4, 6, 9, 17, 19–21, 23, 25–26, 28, 30, 33, 36
   migrate.py16193%24
TOTAL7806891% 

Tests Skipped Failures Errors Time
1376 0 💤 0 ❌ 0 🔥 46.269s ⏱️

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@erdem erdem merged commit 945c15c into main Jan 5, 2026
28 checks passed
@erdem erdem deleted the misc/django-60-support branch January 5, 2026 15:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant