diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 688cd58e2c2..0ccc38ba8dd 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -162,3 +162,9 @@ class Command(BaseCommand): else: if verbosity > 0: print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count) + + # Close the DB connection. This is required as a workaround for an + # edge case in MySQL: if the same connection is used to + # create tables, load data, and query, the query can return + # incorrect results. See Django #7572, MySQL #37735. + connection.close() diff --git a/tests/regressiontests/fixtures_regress/fixtures/big-fixture.json b/tests/regressiontests/fixtures_regress/fixtures/big-fixture.json new file mode 100644 index 00000000000..e655fbbf3fc --- /dev/null +++ b/tests/regressiontests/fixtures_regress/fixtures/big-fixture.json @@ -0,0 +1,83 @@ +[ + { + "pk": 6, + "model": "fixtures_regress.channel", + "fields": { + "name": "Business" + } + }, + + { + "pk": 1, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 1", + "channels": [6] + } + }, + { + "pk": 2, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 2", + "channels": [6] + } + }, + { + "pk": 3, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 3", + "channels": [6] + } + }, + { + "pk": 4, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 4", + "channels": [6] + } + }, + + { + "pk": 5, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 5", + "channels": [6] + } + }, + { + "pk": 6, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 6", + "channels": [6] + } + }, + { + "pk": 7, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 7", + "channels": [6] + } + }, + { + "pk": 8, + "model": "fixtures_regress.article", + "fields": { + "title": "Article Title 8", + "channels": [6] + } + }, + { + "pk": 9, + "model": "fixtures_regress.article", + "fields": { + "title": "Yet Another Article", + "channels": [6] + } + } +] \ No newline at end of file diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py index 56ed73169d2..2c048dc0b80 100644 --- a/tests/regressiontests/fixtures_regress/models.py +++ b/tests/regressiontests/fixtures_regress/models.py @@ -44,6 +44,16 @@ class Parent(models.Model): class Child(Parent): data = models.CharField(max_length=10) +# Models to regresison check #7572 +class Channel(models.Model): + name = models.CharField(max_length=255) + +class Article(models.Model): + title = models.CharField(max_length=255) + channels = models.ManyToManyField(Channel) + + class Meta: + ordering = ('id',) __test__ = {'API_TESTS':""" >>> from django.core import management @@ -107,4 +117,21 @@ No fixture data found for 'bad_fixture2'. (File format may be invalid.) >>> management.call_command('loaddata', 'model-inheritance.json', verbosity=0) +############################################### +# Test for ticket #7572 -- MySQL has a problem if the same connection is +# used to create tables, load data, and then query over that data. +# To compensate, we close the connection after running loaddata. +# This ensures that a new connection is opened when test queries are issued. + +>>> management.call_command('loaddata', 'big-fixture.json', verbosity=0) + +>>> articles = Article.objects.exclude(id=9) +>>> articles.values_list('id', flat=True) +[1, 2, 3, 4, 5, 6, 7, 8] + +# Just for good measure, run the same query again. Under the influence of +# ticket #7572, this will give a different result to the previous call. +>>> articles.values_list('id', flat=True) +[1, 2, 3, 4, 5, 6, 7, 8] + """}