[1.7.x] Fixed #23092: Squashing handles external dependencies
This commit is contained in:
parent
cc875e94cf
commit
8e7fdfdb6f
@ -3,11 +3,13 @@ from optparse import make_option
|
|||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.conf import settings
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS, migrations
|
from django.db import connections, DEFAULT_DB_ALIAS, migrations
|
||||||
from django.db.migrations.loader import AmbiguityError
|
from django.db.migrations.loader import AmbiguityError
|
||||||
from django.db.migrations.executor import MigrationExecutor
|
from django.db.migrations.executor import MigrationExecutor
|
||||||
from django.db.migrations.writer import MigrationWriter
|
from django.db.migrations.writer import MigrationWriter
|
||||||
from django.db.migrations.optimizer import MigrationOptimizer
|
from django.db.migrations.optimizer import MigrationOptimizer
|
||||||
|
from django.db.migrations.migration import SwappableTuple
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@ -67,12 +69,23 @@ class Command(BaseCommand):
|
|||||||
if answer != "y":
|
if answer != "y":
|
||||||
return
|
return
|
||||||
|
|
||||||
# Load the operations from all those migrations and concat together
|
# Load the operations from all those migrations and concat together,
|
||||||
|
# along with collecting external dependencies and detecting
|
||||||
|
# double-squashing
|
||||||
operations = []
|
operations = []
|
||||||
|
dependencies = set()
|
||||||
for smigration in migrations_to_squash:
|
for smigration in migrations_to_squash:
|
||||||
if smigration.replaces:
|
if smigration.replaces:
|
||||||
raise CommandError("You cannot squash squashed migrations! Please transition it to a normal migration first: https://docs.djangoproject.com/en/1.7/topics/migrations/#squashing-migrations")
|
raise CommandError("You cannot squash squashed migrations! Please transition it to a normal migration first: https://docs.djangoproject.com/en/1.7/topics/migrations/#squashing-migrations")
|
||||||
operations.extend(smigration.operations)
|
operations.extend(smigration.operations)
|
||||||
|
for dependency in smigration.dependencies:
|
||||||
|
if isinstance(dependency, SwappableTuple):
|
||||||
|
if settings.AUTH_USER_MODEL == dependency.setting:
|
||||||
|
dependencies.add(("__setting__", "AUTH_USER_MODEL"))
|
||||||
|
else:
|
||||||
|
dependencies.add(dependency)
|
||||||
|
elif dependency[0] != smigration.app_label:
|
||||||
|
dependencies.add(dependency)
|
||||||
|
|
||||||
if self.verbosity > 0:
|
if self.verbosity > 0:
|
||||||
self.stdout.write(self.style.MIGRATE_HEADING("Optimizing..."))
|
self.stdout.write(self.style.MIGRATE_HEADING("Optimizing..."))
|
||||||
@ -97,7 +110,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
# Make a new migration with those operations
|
# Make a new migration with those operations
|
||||||
subclass = type("Migration", (migrations.Migration, ), {
|
subclass = type("Migration", (migrations.Migration, ), {
|
||||||
"dependencies": [],
|
"dependencies": dependencies,
|
||||||
"operations": new_operations,
|
"operations": new_operations,
|
||||||
"replaces": replaces,
|
"replaces": replaces,
|
||||||
})
|
})
|
||||||
|
@ -146,8 +146,20 @@ class Migration(object):
|
|||||||
return project_state
|
return project_state
|
||||||
|
|
||||||
|
|
||||||
|
class SwappableTuple(tuple):
|
||||||
|
"""
|
||||||
|
Subclass of tuple so Django can tell this was originally a swappable
|
||||||
|
dependency when it reads the migration file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __new__(cls, value, setting):
|
||||||
|
self = tuple.__new__(cls, value)
|
||||||
|
self.setting = setting
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
def swappable_dependency(value):
|
def swappable_dependency(value):
|
||||||
"""
|
"""
|
||||||
Turns a setting value into a dependency.
|
Turns a setting value into a dependency.
|
||||||
"""
|
"""
|
||||||
return (value.split(".", 1)[0], "__first__")
|
return SwappableTuple((value.split(".", 1)[0], "__first__"), value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user