diff options
| author | Karen Tracey <kmtracey@gmail.com> | 2011-08-07 00:43:26 +0000 |
|---|---|---|
| committer | Karen Tracey <kmtracey@gmail.com> | 2011-08-07 00:43:26 +0000 |
| commit | be87f0b0ec992e6f3e72735d8e95c654da969f6d (patch) | |
| tree | fa4d16b640e716dcd8271f2e6a7e3bb2953cbe5d /tests/regressiontests | |
| parent | e3c89346d217fca92b62a6d11df6b4b6d5be28a2 (diff) | |
Fixed #3615: Added support for loading fixtures with forward references on database backends (such as MySQL/InnoDB) that do not support deferred constraint checking. Many thanks to jsdalton for coming up with a clever solution to this long-standing issue, and to jacob, ramiro, graham_king, and russellm for review/testing. (Apologies if I missed anyone else who helped here.)
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16590 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests')
| -rw-r--r-- | tests/regressiontests/backends/tests.py | 64 | ||||
| -rw-r--r-- | tests/regressiontests/fixtures_regress/tests.py | 29 | ||||
| -rw-r--r-- | tests/regressiontests/introspection/tests.py | 10 | ||||
| -rw-r--r-- | tests/regressiontests/serializers_regress/tests.py | 5 |
4 files changed, 104 insertions, 4 deletions
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index 29db6a705a..27d3dfdddc 100644 --- a/tests/regressiontests/backends/tests.py +++ b/tests/regressiontests/backends/tests.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- # Unit and doctests for specific database backends. +from __future__ import with_statement import datetime from django.conf import settings from django.core.management.color import no_style -from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError +from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError, transaction from django.db.backends.signals import connection_created from django.db.backends.postgresql_psycopg2 import version as pg_version from django.test import TestCase, skipUnlessDBFeature, TransactionTestCase @@ -328,7 +329,8 @@ class FkConstraintsTests(TransactionTestCase): try: a.save() except IntegrityError: - pass + return + self.skipTest("This backend does not support integrity checks.") def test_integrity_checks_on_update(self): """ @@ -343,4 +345,60 @@ class FkConstraintsTests(TransactionTestCase): try: a.save() except IntegrityError: - pass + return + self.skipTest("This backend does not support integrity checks.") + + def test_disable_constraint_checks_manually(self): + """ + When constraint checks are disabled, should be able to write bad data without IntegrityErrors. + """ + with transaction.commit_manually(): + # Create an Article. + models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) + # Retrive it from the DB + a = models.Article.objects.get(headline="Test article") + a.reporter_id = 30 + try: + connection.disable_constraint_checking() + a.save() + connection.enable_constraint_checking() + except IntegrityError: + self.fail("IntegrityError should not have occurred.") + finally: + transaction.rollback() + + def test_disable_constraint_checks_context_manager(self): + """ + When constraint checks are disabled (using context manager), should be able to write bad data without IntegrityErrors. + """ + with transaction.commit_manually(): + # Create an Article. + models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) + # Retrive it from the DB + a = models.Article.objects.get(headline="Test article") + a.reporter_id = 30 + try: + with connection.constraint_checks_disabled(): + a.save() + except IntegrityError: + self.fail("IntegrityError should not have occurred.") + finally: + transaction.rollback() + + def test_check_constraints(self): + """ + Constraint checks should raise an IntegrityError when bad data is in the DB. + """ + with transaction.commit_manually(): + # Create an Article. + models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) + # Retrive it from the DB + a = models.Article.objects.get(headline="Test article") + a.reporter_id = 30 + try: + with connection.constraint_checks_disabled(): + a.save() + with self.assertRaises(IntegrityError): + connection.check_constraints() + finally: + transaction.rollback() diff --git a/tests/regressiontests/fixtures_regress/tests.py b/tests/regressiontests/fixtures_regress/tests.py index a565ec96e0..b67155d426 100644 --- a/tests/regressiontests/fixtures_regress/tests.py +++ b/tests/regressiontests/fixtures_regress/tests.py @@ -362,6 +362,35 @@ class TestFixtures(TestCase): % widget.pk ) + def test_loaddata_works_when_fixture_has_forward_refs(self): + """ + Regression for #3615 - Forward references cause fixtures not to load in MySQL (InnoDB) + """ + management.call_command( + 'loaddata', + 'forward_ref.json', + verbosity=0, + commit=False + ) + self.assertEqual(Book.objects.all()[0].id, 1) + self.assertEqual(Person.objects.all()[0].id, 4) + + def test_loaddata_raises_error_when_fixture_has_invalid_foreign_key(self): + """ + Regression for #3615 - Ensure data with nonexistent child key references raises error + """ + stderr = StringIO() + management.call_command( + 'loaddata', + 'forward_ref_bad_data.json', + verbosity=0, + commit=False, + stderr=stderr, + ) + self.assertTrue( + stderr.getvalue().startswith('Problem installing fixture') + ) + class NaturalKeyFixtureTests(TestCase): def assertRaisesMessage(self, exc, msg, func, *args, **kwargs): diff --git a/tests/regressiontests/introspection/tests.py b/tests/regressiontests/introspection/tests.py index 4f5fb09193..fdf30126cd 100644 --- a/tests/regressiontests/introspection/tests.py +++ b/tests/regressiontests/introspection/tests.py @@ -95,6 +95,16 @@ class IntrospectionTests(TestCase): # That's {field_index: (field_index_other_table, other_table)} self.assertEqual(relations, {3: (0, Reporter._meta.db_table)}) + def test_get_key_columns(self): + cursor = connection.cursor() + key_columns = connection.introspection.get_key_columns(cursor, Article._meta.db_table) + self.assertEqual(key_columns, [(u'reporter_id', Reporter._meta.db_table, u'id')]) + + def test_get_primary_key_column(self): + cursor = connection.cursor() + primary_key_column = connection.introspection.get_primary_key_column(cursor, Article._meta.db_table) + self.assertEqual(primary_key_column, u'id') + def test_get_indexes(self): cursor = connection.cursor() indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index cd2ce3cc9a..bb6f598719 100644 --- a/tests/regressiontests/serializers_regress/tests.py +++ b/tests/regressiontests/serializers_regress/tests.py @@ -6,6 +6,8 @@ test case that is capable of testing the capabilities of the serializers. This includes all valid data values, plus forward, backwards and self references. """ +# This is necessary in Python 2.5 to enable the with statement, in 2.6 +# and up it is no longer necessary. from __future__ import with_statement import datetime @@ -382,7 +384,8 @@ def serializerTest(format, self): objects = [] instance_count = {} for (func, pk, klass, datum) in test_data: - objects.extend(func[0](pk, klass, datum)) + with connection.constraint_checks_disabled(): + objects.extend(func[0](pk, klass, datum)) # Get a count of the number of objects created for each class for klass in instance_count: |
