mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
The new signature enables better support for routing RunPython and
RunSQL operations, especially w.r.t. reusable and third-party apps.
This commit also takes advantage of the deprecation cycle for the old
signature to remove the backward incompatibility introduced in #22583;
RunPython and RunSQL won't call allow_migrate() when when the router
has the old signature.
Thanks Aymeric Augustin and Tim Graham for helping shape up the patch.
Refs 22583.
Conflicts:
django/db/utils.py
Backport of bed504d70b from master
This commit is contained in:
@@ -404,7 +404,7 @@ class BaseDatabaseCreation(object):
|
||||
def get_objects():
|
||||
for model in serializers.sort_dependencies(app_list):
|
||||
if (not model._meta.proxy and model._meta.managed and
|
||||
router.allow_migrate(self.connection.alias, model)):
|
||||
router.allow_migrate_model(self.connection.alias, model)):
|
||||
queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
|
||||
for obj in queryset.iterator():
|
||||
yield obj
|
||||
|
||||
@@ -99,15 +99,17 @@ class Operation(object):
|
||||
"""
|
||||
return self.references_model(model_name, app_label)
|
||||
|
||||
def allowed_to_migrate(self, connection_alias, model, hints=None):
|
||||
def allow_migrate_model(self, connection_alias, model):
|
||||
"""
|
||||
Returns if we're allowed to migrate the model.
|
||||
|
||||
This is a thin wrapper around router.allow_migrate_model() that
|
||||
preemptively rejects any proxy, swapped out, or unmanaged model.
|
||||
"""
|
||||
# Always skip if proxy, swapped out, or unmanaged.
|
||||
if model and (model._meta.proxy or model._meta.swapped or not model._meta.managed):
|
||||
if model._meta.proxy or model._meta.swapped or not model._meta.managed:
|
||||
return False
|
||||
|
||||
return router.allow_migrate(connection_alias, model, **(hints or {}))
|
||||
return router.allow_migrate_model(connection_alias, model)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s %s%s>" % (
|
||||
|
||||
@@ -52,7 +52,7 @@ class AddField(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
to_model = to_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, to_model):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
field = to_model._meta.get_field(self.name)
|
||||
if not self.preserve_default:
|
||||
@@ -66,7 +66,7 @@ class AddField(Operation):
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, from_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, from_model):
|
||||
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
|
||||
|
||||
def describe(self):
|
||||
@@ -117,12 +117,12 @@ class RemoveField(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, from_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, from_model):
|
||||
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
to_model = to_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, to_model):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
schema_editor.add_field(from_model, to_model._meta.get_field(self.name))
|
||||
|
||||
@@ -184,7 +184,7 @@ class AlterField(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
to_model = to_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, to_model):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
from_field = from_model._meta.get_field(self.name)
|
||||
to_field = to_model._meta.get_field(self.name)
|
||||
@@ -267,7 +267,7 @@ class RenameField(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
to_model = to_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, to_model):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
schema_editor.alter_field(
|
||||
from_model,
|
||||
@@ -277,7 +277,7 @@ class RenameField(Operation):
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
to_model = to_state.apps.get_model(app_label, self.model_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, to_model):
|
||||
from_model = from_state.apps.get_model(app_label, self.model_name)
|
||||
schema_editor.alter_field(
|
||||
from_model,
|
||||
|
||||
@@ -55,12 +55,12 @@ class CreateModel(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
model = to_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, model):
|
||||
schema_editor.create_model(model)
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
model = from_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, model):
|
||||
schema_editor.delete_model(model)
|
||||
|
||||
def describe(self):
|
||||
@@ -111,12 +111,12 @@ class DeleteModel(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
model = from_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, model):
|
||||
schema_editor.delete_model(model)
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
model = to_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, model):
|
||||
schema_editor.create_model(model)
|
||||
|
||||
def references_model(self, name, app_label=None):
|
||||
@@ -189,7 +189,7 @@ class RenameModel(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
new_model = to_state.apps.get_model(app_label, self.new_name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, new_model):
|
||||
old_model = from_state.apps.get_model(app_label, self.old_name)
|
||||
# Move the main table
|
||||
schema_editor.alter_db_table(
|
||||
@@ -287,7 +287,7 @@ class AlterModelTable(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
new_model = to_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, new_model):
|
||||
old_model = from_state.apps.get_model(app_label, self.name)
|
||||
schema_editor.alter_db_table(
|
||||
new_model,
|
||||
@@ -347,7 +347,7 @@ class AlterUniqueTogether(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
new_model = to_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, new_model):
|
||||
old_model = from_state.apps.get_model(app_label, self.name)
|
||||
schema_editor.alter_unique_together(
|
||||
new_model,
|
||||
@@ -399,7 +399,7 @@ class AlterIndexTogether(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
new_model = to_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, new_model):
|
||||
old_model = from_state.apps.get_model(app_label, self.name)
|
||||
schema_editor.alter_index_together(
|
||||
new_model,
|
||||
@@ -448,7 +448,7 @@ class AlterOrderWithRespectTo(Operation):
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
to_model = to_state.apps.get_model(app_label, self.name)
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
|
||||
if self.allow_migrate_model(schema_editor.connection.alias, to_model):
|
||||
from_model = from_state.apps.get_model(app_label, self.name)
|
||||
# Remove a field if we need to
|
||||
if from_model._meta.order_with_respect_to and not to_model._meta.order_with_respect_to:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import router
|
||||
|
||||
from .base import Operation
|
||||
|
||||
|
||||
@@ -94,13 +96,13 @@ class RunSQL(Operation):
|
||||
state_operation.state_forwards(app_label, state)
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
|
||||
if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
|
||||
self._run_sql(schema_editor, self.sql)
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
if self.reverse_sql is None:
|
||||
raise NotImplementedError("You cannot reverse this operation")
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
|
||||
if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
|
||||
self._run_sql(schema_editor, self.reverse_sql)
|
||||
|
||||
def describe(self):
|
||||
@@ -171,7 +173,7 @@ class RunPython(Operation):
|
||||
pass
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
|
||||
if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
|
||||
# We now execute the Python code in a context that contains a 'models'
|
||||
# object, representing the versioned models as an app registry.
|
||||
# We could try to override the global cache, but then people will still
|
||||
@@ -181,7 +183,7 @@ class RunPython(Operation):
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
if self.reverse_code is None:
|
||||
raise NotImplementedError("You cannot reverse this operation")
|
||||
if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
|
||||
if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
|
||||
self.reverse_code(from_state.apps, schema_editor)
|
||||
|
||||
def describe(self):
|
||||
|
||||
@@ -1582,7 +1582,7 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
# Find the minimum max allowed length among all specified db_aliases.
|
||||
for db in settings.DATABASES.keys():
|
||||
# skip databases where the model won't be created
|
||||
if not router.allow_migrate(db, cls):
|
||||
if not router.allow_migrate_model(db, cls):
|
||||
continue
|
||||
connection = connections[db]
|
||||
max_name_length = connection.ops.max_name_length()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import inspect
|
||||
import os
|
||||
import pkgutil
|
||||
import warnings
|
||||
@@ -8,7 +9,9 @@ from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils import six
|
||||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango19Warning
|
||||
from django.utils.deprecation import (
|
||||
RemovedInDjango19Warning, RemovedInDjango20Warning,
|
||||
)
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.module_loading import import_string
|
||||
|
||||
@@ -315,7 +318,7 @@ class ConnectionRouter(object):
|
||||
return allow
|
||||
return obj1._state.db == obj2._state.db
|
||||
|
||||
def allow_migrate(self, db, model, **hints):
|
||||
def allow_migrate(self, db, app_label, **hints):
|
||||
for router in self.routers:
|
||||
try:
|
||||
try:
|
||||
@@ -328,16 +331,36 @@ class ConnectionRouter(object):
|
||||
RemovedInDjango19Warning, stacklevel=2)
|
||||
except AttributeError:
|
||||
# If the router doesn't have a method, skip to the next one.
|
||||
pass
|
||||
continue
|
||||
|
||||
argspec = inspect.getargspec(router.allow_migrate)
|
||||
if len(argspec.args) == 3 and not argspec.keywords:
|
||||
warnings.warn(
|
||||
"The signature of allow_migrate has changed from "
|
||||
"allow_migrate(self, db, model) to "
|
||||
"allow_migrate(self, db, app_label, model_name=None, **hints). "
|
||||
"Support for the old signature will be removed in Django 2.0.",
|
||||
RemovedInDjango20Warning)
|
||||
model = hints.get('model')
|
||||
allow = None if model is None else method(db, model)
|
||||
else:
|
||||
allow = method(db, model, **hints)
|
||||
if allow is not None:
|
||||
return allow
|
||||
allow = method(db, app_label, **hints)
|
||||
|
||||
if allow is not None:
|
||||
return allow
|
||||
return True
|
||||
|
||||
def allow_migrate_model(self, db, model):
|
||||
return self.allow_migrate(
|
||||
db,
|
||||
model._meta.app_label,
|
||||
model_name=model._meta.model_name,
|
||||
model=model,
|
||||
)
|
||||
|
||||
def get_migratable_models(self, app_config, db, include_auto_created=False):
|
||||
"""
|
||||
Return app models allowed to be synchronized on provided db.
|
||||
"""
|
||||
models = app_config.get_models(include_auto_created=include_auto_created)
|
||||
return [model for model in models if self.allow_migrate(db, model)]
|
||||
return [model for model in models if self.allow_migrate_model(db, model)]
|
||||
|
||||
Reference in New Issue
Block a user