diff options
| author | Loic Bistuer <loic.bistuer@gmail.com> | 2015-02-19 14:27:58 +0700 |
|---|---|---|
| committer | Loic Bistuer <loic.bistuer@gmail.com> | 2015-02-20 21:34:09 +0700 |
| commit | bed504d70bede3431a213203c13a33905d6dbf77 (patch) | |
| tree | b2216527abc707e3d48220017a107c93736b9f7a /django | |
| parent | dd0b487872de4e3ff966da51e3610bac996e44f0 (diff) | |
Fixed #24351, #24346 -- Changed the signature of allow_migrate().
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.
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/auth/management/__init__.py | 2 | ||||
| -rw-r--r-- | django/contrib/contenttypes/management.py | 2 | ||||
| -rw-r--r-- | django/contrib/contenttypes/migrations/0002_remove_content_type_name.py | 1 | ||||
| -rw-r--r-- | django/contrib/sites/management.py | 2 | ||||
| -rw-r--r-- | django/core/cache/backends/db.py | 1 | ||||
| -rw-r--r-- | django/core/management/commands/createcachetable.py | 2 | ||||
| -rw-r--r-- | django/core/management/commands/dumpdata.py | 2 | ||||
| -rw-r--r-- | django/core/management/commands/loaddata.py | 2 | ||||
| -rw-r--r-- | django/db/backends/base/creation.py | 2 | ||||
| -rw-r--r-- | django/db/migrations/operations/base.py | 10 | ||||
| -rw-r--r-- | django/db/migrations/operations/fields.py | 14 | ||||
| -rw-r--r-- | django/db/migrations/operations/models.py | 18 | ||||
| -rw-r--r-- | django/db/migrations/operations/special.py | 10 | ||||
| -rw-r--r-- | django/db/models/base.py | 2 | ||||
| -rw-r--r-- | django/db/utils.py | 35 |
15 files changed, 67 insertions, 38 deletions
diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 44d8563c14..ea05d2b497 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -66,7 +66,7 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_ except LookupError: return - if not router.allow_migrate(using, Permission): + if not router.allow_migrate_model(using, Permission): return from django.contrib.contenttypes.models import ContentType diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py index 6364c752d2..bfc25b3405 100644 --- a/django/contrib/contenttypes/management.py +++ b/django/contrib/contenttypes/management.py @@ -17,7 +17,7 @@ def update_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT except LookupError: return - if not router.allow_migrate(using, ContentType): + if not router.allow_migrate_model(using, ContentType): return ContentType.objects.clear_cache() diff --git a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py index 044fb615cf..8bd8032b41 100644 --- a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py +++ b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py @@ -33,6 +33,7 @@ class Migration(migrations.Migration): migrations.RunPython( migrations.RunPython.noop, add_legacy_name, + hints={'model_name': 'contenttype'}, ), migrations.RemoveField( model_name='contenttype', diff --git a/django/contrib/sites/management.py b/django/contrib/sites/management.py index 7c6c32d95b..5647b6a304 100644 --- a/django/contrib/sites/management.py +++ b/django/contrib/sites/management.py @@ -14,7 +14,7 @@ def create_default_site(app_config, verbosity=2, interactive=True, using=DEFAULT except LookupError: return - if not router.allow_migrate(using, Site): + if not router.allow_migrate_model(using, Site): return if not Site.objects.using(using).exists(): diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index f016179491..a41b611d5b 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -30,6 +30,7 @@ class Options(object): self.abstract = False self.managed = True self.proxy = False + self.swapped = False class BaseDatabaseCache(BaseCache): diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py index 750e787200..4c014c88fd 100644 --- a/django/core/management/commands/createcachetable.py +++ b/django/core/management/commands/createcachetable.py @@ -38,7 +38,7 @@ class Command(BaseCommand): def create_table(self, database, tablename): cache = BaseDatabaseCache(tablename, {}) - if not router.allow_migrate(database, cache.cache_model_class): + if not router.allow_migrate_model(database, cache.cache_model_class): return connection = connections[database] diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py index a7c8bd7615..da1584d561 100644 --- a/django/core/management/commands/dumpdata.py +++ b/django/core/management/commands/dumpdata.py @@ -132,7 +132,7 @@ class Command(BaseCommand): for model in serializers.sort_dependencies(app_list.items()): if model in excluded_models: continue - if not model._meta.proxy and router.allow_migrate(using, model): + if not model._meta.proxy and router.allow_migrate_model(using, model): if use_base_manager: objects = model._base_manager else: diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index a07f6b7300..464e19ce0c 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -139,7 +139,7 @@ class Command(BaseCommand): for obj in objects: objects_in_fixture += 1 - if router.allow_migrate(self.using, obj.object.__class__): + if router.allow_migrate_model(self.using, obj.object.__class__): loaded_objects_in_fixture += 1 self.models.add(obj.object.__class__) try: diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index 854e17b6c2..a5e69ceedb 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -107,7 +107,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 diff --git a/django/db/migrations/operations/base.py b/django/db/migrations/operations/base.py index 557c956732..b750a1e4be 100644 --- a/django/db/migrations/operations/base.py +++ b/django/db/migrations/operations/base.py @@ -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>" % ( diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py index 70e7a0f296..e00cfa66e2 100644 --- a/django/db/migrations/operations/fields.py +++ b/django/db/migrations/operations/fields.py @@ -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, diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py index 99df8a073e..efd35f0501 100644 --- a/django/db/migrations/operations/models.py +++ b/django/db/migrations/operations/models.py @@ -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: diff --git a/django/db/migrations/operations/special.py b/django/db/migrations/operations/special.py index 91261f724f..2c995c54ac 100644 --- a/django/db/migrations/operations/special.py +++ b/django/db/migrations/operations/special.py @@ -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): diff --git a/django/db/models/base.py b/django/db/models/base.py index d906f2e461..60daa105b2 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1549,7 +1549,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() diff --git a/django/db/utils.py b/django/db/utils.py index 0480adf2dc..d038c20368 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -1,5 +1,7 @@ +import inspect import os import pkgutil +import warnings from importlib import import_module from threading import local @@ -7,6 +9,7 @@ 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 RemovedInDjango20Warning from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -276,22 +279,42 @@ 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: method = router.allow_migrate 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)] |
