diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index af108e08e1..d384ea4c7e 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -85,6 +85,16 @@ class Command(BaseCommand): if has_bz2: self.compression_formats['bz2'] = (bz2.BZ2File, 'r') + # Django's test suite repeatedly tries to load initial_data fixtures + # from apps that don't have any fixtures. Because disabling constraint + # checks can be expensive on some database (especially MSSQL), bail + # out early if no fixtures are found. + for fixture_label in fixture_labels: + if self.find_fixtures(fixture_label): + break + else: + return + with connection.constraint_checks_disabled(): for fixture_label in fixture_labels: self.load_label(fixture_label) diff --git a/docs/releases/1.8.8.txt b/docs/releases/1.8.8.txt index 8caf5f7ff5..a888925841 100644 --- a/docs/releases/1.8.8.txt +++ b/docs/releases/1.8.8.txt @@ -51,3 +51,6 @@ Bugfixes * Fixed a regression in the admin which ignored line breaks in read-only fields instead of converting them to ``
`` (:ticket:`25465`). + +* Made ``loaddata`` skip disabling and enabling database constraints when it + doesn't load any fixtures (:ticket:`23372`). diff --git a/docs/releases/1.9.1.txt b/docs/releases/1.9.1.txt index 9af92e30ef..a01eb09d19 100644 --- a/docs/releases/1.9.1.txt +++ b/docs/releases/1.9.1.txt @@ -73,3 +73,6 @@ Bugfixes * Fixed incorrect object reference in ``SingleObjectMixin.get_context_object_name()`` (:ticket:`26006`). + +* Made ``loaddata`` skip disabling and enabling database constraints when it + doesn't load any fixtures (:ticket:`23372`). diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index f48a689f6f..86164e03bc 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -13,7 +13,7 @@ from django.core.files.temp import NamedTemporaryFile from django.core.serializers.base import ProgressBar from django.db import IntegrityError, connection from django.test import ( - TestCase, TransactionTestCase, ignore_warnings, skipUnlessDBFeature, + TestCase, TransactionTestCase, ignore_warnings, mock, skipUnlessDBFeature, ) from django.utils import six from django.utils.encoding import force_text @@ -643,6 +643,18 @@ class NonExistentFixtureTests(TestCase): self.assertEqual(force_text(w[0].message), "No fixture named 'this_fixture_doesnt_exist' found.") + @mock.patch('django.db.connection.enable_constraint_checking') + @mock.patch('django.db.connection.disable_constraint_checking') + def test_nonexistent_fixture_no_constraint_checking(self, + disable_constraint_checking, enable_constraint_checking): + """ + If no fixtures match the loaddata command, constraints checks on the + database shouldn't be disabled. This is performance critical on MSSQL. + """ + management.call_command('loaddata', 'this_fixture_doesnt_exist', verbosity=0) + disable_constraint_checking.assert_not_called() + enable_constraint_checking.assert_not_called() + class FixtureTransactionTests(DumpDataAssertMixin, TransactionTestCase):