summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2015-12-29 18:29:11 +0200
committerTim Graham <timograham@gmail.com>2015-12-31 09:05:20 -0500
commit99569b22d93737f6304ffe808ebf1d0d711fedd9 (patch)
tree26ca960d00dee5b43fa416236d0e6485e52e19f3
parentb37cb0b95878c9356693f129334778f00f44a1bc (diff)
[1.9.x] Fixed #23372 -- Made loaddata faster if it doesn't find any fixtures.
Django's test suite often tries to load fixture files from apps that have no fixtures at all. This creates a lot of unnecessary disabling and enabling of constraints which can be expensive on some database. To speed this up, loaddata now first checks if any fixture file matches. If no fixture file is matched, then the command exits before disabling and enabling of constraints is done. The main benefit of this change is seen on MSSQL, where tests on Django 1.8 run hours faster. Backport of ee9f4686b19e2b4a68f5cb4f9d61dc045c1d4c63 from master
-rw-r--r--django/core/management/commands/loaddata.py10
-rw-r--r--docs/releases/1.8.8.txt3
-rw-r--r--docs/releases/1.9.1.txt3
-rw-r--r--tests/fixtures/tests.py14
4 files changed, 29 insertions, 1 deletions
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 ``<br>`` (: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):