Ticket #11665: better_constraint_checks_during_testing.v1.diff
File better_constraint_checks_during_testing.v1.diff, 32.9 KB (added by , 13 years ago) |
---|
-
django/core/management/commands/loaddata.py
diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 34f3543..0aa07f4 100644
a b 1 # This is necessary in Python 2.5 to enable the with statement, in 2.6 2 # and up it is no longer necessary. 3 from __future__ import with_statement 4 1 5 import sys 2 6 import os 3 7 import gzip … … class Command(BaseCommand): 166 170 (format, fixture_name, humanize(fixture_dir))) 167 171 try: 168 172 objects = serializers.deserialize(format, fixture, using=using) 169 for obj in objects: 170 objects_in_fixture += 1 171 if router.allow_syncdb(using, obj.object.__class__): 172 loaded_objects_in_fixture += 1 173 models.add(obj.object.__class__) 174 obj.save(using=using) 173 174 with connection.constraint_checks_disabled(): 175 for obj in objects: 176 objects_in_fixture += 1 177 if router.allow_syncdb(using, obj.object.__class__): 178 loaded_objects_in_fixture += 1 179 models.add(obj.object.__class__) 180 obj.save(using=using) 181 182 # Since we disabled constraint checks, we must manually check for 183 # any invalid keys that might have been added 184 table_names = [model._meta.db_table for model in models] 185 connection.check_constraints(table_names=table_names) 186 175 187 loaded_object_count += loaded_objects_in_fixture 176 188 fixture_object_count += objects_in_fixture 177 189 label_found = True -
django/db/backends/__init__.py
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index 1c3bc7e..e4f40a8 100644
a b try: 3 3 except ImportError: 4 4 import dummy_thread as thread 5 5 from threading import local 6 from contextlib import contextmanager 6 7 7 8 from django.conf import settings 8 9 from django.db import DEFAULT_DB_ALIAS … … class BaseDatabaseWrapper(local): 237 238 """ 238 239 if self.savepoint_state: 239 240 self._savepoint_commit(sid) 241 242 @contextmanager 243 def constraint_checks_disabled(self): 244 disabled = self.disable_constraint_checking() 245 try: 246 yield 247 finally: 248 if disabled: 249 self.enable_constraint_checking() 250 251 252 def disable_constraint_checking(self): 253 """ 254 Backends can implement as needed to temporarily disable foreign key constraint 255 checking. 256 """ 257 pass 258 259 def enable_constraint_checking(self): 260 """ 261 Backends can implement as needed to re-enable foreign key constraint checking. 262 """ 263 pass 264 265 def check_constraints(self, table_names=None): 266 """ 267 Backends can override this method if they can apply constraint checking (e.g. via "SET CONSTRAINTS 268 ALL IMMEDIATE"). Should raise an IntegrityError if any invalid foreign key references are encountered. 269 """ 270 pass 240 271 241 272 def close(self): 242 273 if self.connection is not None: … … class BaseDatabaseIntrospection(object): 869 900 870 901 return sequence_list 871 902 903 def get_key_columns(self, cursor, table_name): 904 """ 905 Backends can override this to return a list of (column_name, referenced_table_name, 906 referenced_column_name) for all key columns in given table. 907 """ 908 raise NotImplementedError 909 910 def get_primary_key_column(self, cursor, table_name): 911 """ 912 Backends can override this to return the column name of the primary key for the given table. 913 """ 914 raise NotImplementedError 915 872 916 class BaseDatabaseClient(object): 873 917 """ 874 918 This class encapsulates all backend-specific methods for opening a -
django/db/backends/dummy/base.py
diff --git a/django/db/backends/dummy/base.py b/django/db/backends/dummy/base.py index 7de48c8..746f26b 100644
a b class DatabaseIntrospection(BaseDatabaseIntrospection): 34 34 get_table_description = complain 35 35 get_relations = complain 36 36 get_indexes = complain 37 get_key_columns = complain 37 38 38 39 class DatabaseWrapper(BaseDatabaseWrapper): 39 40 operators = {} -
django/db/backends/mysql/base.py
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 6d02aa7..fc714da 100644
a b class DatabaseWrapper(BaseDatabaseWrapper): 349 349 raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info()) 350 350 self.server_version = tuple([int(x) for x in m.groups()]) 351 351 return self.server_version 352 353 def disable_constraint_checking(self): 354 """ 355 Disables foreign key checks, primarily for use in adding rows with forward references. Always returns True, 356 to indicate constraint checks need to be re-enabled. 357 """ 358 self.cursor().execute('SET foreign_key_checks=0') 359 return True 360 361 def enable_constraint_checking(self): 362 """ 363 Re-enable foreign key checks after they have been disabled. 364 """ 365 self.cursor().execute('SET foreign_key_checks=1') 366 367 def check_constraints(self, table_names=None): 368 """ 369 Checks each table name in table-names for rows with invalid foreign key references. This method is 370 intended to be used in conjunction with `disable_constraint_checking()` and `enable_constraint_checking()`, to 371 determine if rows with invalid references were entered while constraint checks were off. 372 373 Raises an IntegrityError on the first invalid foreign key reference encountered (if any) and provides 374 detailed information about the invalid reference in the error message. 375 376 Backends can override this method if they can more directly apply constraint checking (e.g. via "SET CONSTRAINTS 377 ALL IMMEDIATE") 378 """ 379 cursor = self.cursor() 380 if table_names is None: 381 table_names = self.introspection.get_table_list(cursor) 382 for table_name in table_names: 383 primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name) 384 if not primary_key_column_name: 385 continue 386 key_columns = self.introspection.get_key_columns(cursor, table_name) 387 for column_name, referenced_table_name, referenced_column_name in key_columns: 388 cursor.execute(""" 389 SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING 390 LEFT JOIN `%s` as REFERRED 391 ON (REFERRING.`%s` = REFERRED.`%s`) 392 WHERE REFERRING.`%s` IS NOT NULL 393 AND REFERRED.`%s` IS NULL""" 394 % (primary_key_column_name, column_name, table_name, referenced_table_name, 395 column_name, referenced_column_name, column_name, referenced_column_name)) 396 for bad_row in cursor.fetchall(): 397 raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid \ 398 foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s." 399 % (table_name, bad_row[0], table_name, column_name, bad_row[1], 400 referenced_table_name, referenced_column_name)) -
django/db/backends/mysql/introspection.py
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py index 9e1518b..4612221 100644
a b class DatabaseIntrospection(BaseDatabaseIntrospection): 51 51 representing all relationships to the given table. Indexes are 0-based. 52 52 """ 53 53 my_field_dict = self._name_to_index(cursor, table_name) 54 constraints = []54 constraints = self.get_key_columns(cursor, table_name) 55 55 relations = {} 56 for my_fieldname, other_table, other_field in constraints: 57 other_field_index = self._name_to_index(cursor, other_table)[other_field] 58 my_field_index = my_field_dict[my_fieldname] 59 relations[my_field_index] = (other_field_index, other_table) 60 return relations 61 62 def get_key_columns(self, cursor, table_name): 63 """ 64 Returns a list of (column_name, referenced_table_name, referenced_column_name) for all 65 key columns in given table. 66 """ 67 key_columns = [] 56 68 try: 57 # This should work for MySQL 5.0.58 69 cursor.execute(""" 59 70 SELECT column_name, referenced_table_name, referenced_column_name 60 71 FROM information_schema.key_column_usage … … class DatabaseIntrospection(BaseDatabaseIntrospection): 62 73 AND table_schema = DATABASE() 63 74 AND referenced_table_name IS NOT NULL 64 75 AND referenced_column_name IS NOT NULL""", [table_name]) 65 constraints.extend(cursor.fetchall())76 key_columns.extend(cursor.fetchall()) 66 77 except (ProgrammingError, OperationalError): 67 78 # Fall back to "SHOW CREATE TABLE", for previous MySQL versions. 68 79 # Go through all constraints and save the equal matches. … … class DatabaseIntrospection(BaseDatabaseIntrospection): 74 85 if match == None: 75 86 break 76 87 pos = match.end() 77 constraints.append(match.groups()) 78 79 for my_fieldname, other_table, other_field in constraints: 80 other_field_index = self._name_to_index(cursor, other_table)[other_field] 81 my_field_index = my_field_dict[my_fieldname] 82 relations[my_field_index] = (other_field_index, other_table) 83 84 return relations 88 key_columns.append(match.groups()) 89 return key_columns 90 91 def get_primary_key_column(self, cursor, table_name): 92 """ 93 Returns the name of the primary key column for the given table 94 """ 95 for column in self.get_indexes(cursor, table_name).iteritems(): 96 if column[1]['primary_key']: 97 return column[0] 98 return None 85 99 86 100 def get_indexes(self, cursor, table_name): 87 101 """ -
django/db/backends/oracle/base.py
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 930b1bb..3cadb66 100644
a b class DatabaseWrapper(BaseDatabaseWrapper): 428 428 self.introspection = DatabaseIntrospection(self) 429 429 self.validation = BaseDatabaseValidation(self) 430 430 431 def check_constraints(self, table_names=None): 432 """ 433 To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they 434 are returned to deferred. 435 """ 436 self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') 437 self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') 438 431 439 def _valid_connection(self): 432 440 return self.connection is not None 433 441 -
django/db/backends/postgresql_psycopg2/base.py
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index 6ed59a6..4136d4f 100644
a b class DatabaseWrapper(BaseDatabaseWrapper): 105 105 self.introspection = DatabaseIntrospection(self) 106 106 self.validation = BaseDatabaseValidation(self) 107 107 self._pg_version = None 108 109 def check_constraints(self, table_names=None): 110 """ 111 To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they 112 are returned to deferred. 113 """ 114 self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE') 115 self.cursor().execute('SET CONSTRAINTS ALL DEFERRED') 108 116 109 117 def _get_pg_version(self): 110 118 if self._pg_version is None: -
django/db/backends/sqlite3/base.py
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 79c5ede..bc16d9a 100644
a b class DatabaseWrapper(BaseDatabaseWrapper): 206 206 connection_created.send(sender=self.__class__, connection=self) 207 207 return self.connection.cursor(factory=SQLiteCursorWrapper) 208 208 209 def check_constraints(self, table_names=None): 210 """ 211 Checks each table name in table-names for rows with invalid foreign key references. This method is 212 intended to be used in conjunction with `disable_constraint_checking()` and `enable_constraint_checking()`, to 213 determine if rows with invalid references were entered while constraint checks were off. 214 215 Raises an IntegrityError on the first invalid foreign key reference encountered (if any) and provides 216 detailed information about the invalid reference in the error message. 217 218 Backends can override this method if they can more directly apply constraint checking (e.g. via "SET CONSTRAINTS 219 ALL IMMEDIATE") 220 """ 221 cursor = self.cursor() 222 if table_names is None: 223 table_names = self.introspection.get_table_list(cursor) 224 for table_name in table_names: 225 primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name) 226 if not primary_key_column_name: 227 continue 228 key_columns = self.introspection.get_key_columns(cursor, table_name) 229 for column_name, referenced_table_name, referenced_column_name in key_columns: 230 cursor.execute(""" 231 SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING 232 LEFT JOIN `%s` as REFERRED 233 ON (REFERRING.`%s` = REFERRED.`%s`) 234 WHERE REFERRING.`%s` IS NOT NULL 235 AND REFERRED.`%s` IS NULL""" 236 % (primary_key_column_name, column_name, table_name, referenced_table_name, 237 column_name, referenced_column_name, column_name, referenced_column_name)) 238 for bad_row in cursor.fetchall(): 239 raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid \ 240 foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s." 241 % (table_name, bad_row[0], table_name, column_name, bad_row[1], 242 referenced_table_name, referenced_column_name)) 243 209 244 def close(self): 210 245 # If database is in memory, closing the connection destroys the 211 246 # database. To prevent accidental data loss, ignore close requests on -
django/db/backends/sqlite3/introspection.py
diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index 5ee7b64..27de913 100644
a b class DatabaseIntrospection(BaseDatabaseIntrospection): 103 103 104 104 return relations 105 105 106 def get_key_columns(self, cursor, table_name): 107 """ 108 Returns a list of (column_name, referenced_table_name, referenced_column_name) for all 109 key columns in given table. 110 """ 111 key_columns = [] 112 113 # Schema for this table 114 cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %s", [table_name, "table"]) 115 results = cursor.fetchone()[0].strip() 116 results = results[results.index('(')+1:results.rindex(')')] 117 118 # Walk through and look for references to other tables. SQLite doesn't 119 # really have enforced references, but since it echoes out the SQL used 120 # to create the table we can look for REFERENCES statements used there. 121 for field_index, field_desc in enumerate(results.split(',')): 122 field_desc = field_desc.strip() 123 if field_desc.startswith("UNIQUE"): 124 continue 125 126 m = re.search('"(.*)".*references (.*) \(["|](.*)["|]\)', field_desc, re.I) 127 if not m: 128 continue 129 130 # This will append (column_name, referenced_table_name, referenced_column_name) to key_columns 131 key_columns.append(tuple([s.strip('"') for s in m.groups()])) 132 133 return key_columns 134 106 135 def get_indexes(self, cursor, table_name): 107 136 """ 108 137 Returns a dictionary of fieldname -> infodict for the given table, … … class DatabaseIntrospection(BaseDatabaseIntrospection): 127 156 name = info[0][2] # seqno, cid, name 128 157 indexes[name]['unique'] = True 129 158 return indexes 159 160 def get_primary_key_column(self, cursor, table_name): 161 """ 162 Get the column name of the primary key for the given table. 163 """ 164 # Don't use PRAGMA because that causes issues with some transactions 165 cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %s", [table_name, "table"]) 166 results = cursor.fetchone()[0].strip() 167 results = results[results.index('(')+1:results.rindex(')')] 168 for field_desc in results.split(','): 169 field_desc = field_desc.strip() 170 m = re.search('"(.*)".*PRIMARY KEY$', field_desc) 171 if m: 172 return m.groups()[0] 173 return None 130 174 131 175 def _table_info(self, cursor, name): 132 176 cursor.execute('PRAGMA table_info(%s)' % self.connection.ops.quote_name(name)) -
django/test/testcases.py
diff --git a/django/test/testcases.py b/django/test/testcases.py index e767712..cc715c8 100644
a b def to_list(value): 39 39 40 40 real_commit = transaction.commit 41 41 real_rollback = transaction.rollback 42 real_commit_unless_managed = transaction.commit_unless_managed 43 real_rollback_unless_managed = transaction.rollback_unless_managed 42 44 real_enter_transaction_management = transaction.enter_transaction_management 43 45 real_leave_transaction_management = transaction.leave_transaction_management 44 46 real_managed = transaction.managed … … real_managed = transaction.managed 46 48 def nop(*args, **kwargs): 47 49 return 48 50 51 def check_constraints(using=None): 52 """ 53 Emulate the constraint check behavior that normally occurs when a transaction is rolled back or committed. 54 """ 55 if using is None: 56 using = DEFAULT_DB_ALIAS 57 connection = connections[using] 58 connection.check_constraints() 59 49 60 def disable_transaction_methods(): 50 transaction.commit = nop61 transaction.commit = check_constraints 51 62 transaction.rollback = nop 63 transaction.commit_unless_managed = check_constraints 64 transaction.rollback_unless_managed = nop 52 65 transaction.enter_transaction_management = nop 53 66 transaction.leave_transaction_management = nop 54 67 transaction.managed = nop … … def disable_transaction_methods(): 56 69 def restore_transaction_methods(): 57 70 transaction.commit = real_commit 58 71 transaction.rollback = real_rollback 72 transaction.commit_unless_managed = real_commit_unless_managed 73 transaction.rollback_unless_managed = real_rollback_unless_managed 59 74 transaction.enter_transaction_management = real_enter_transaction_management 60 75 transaction.leave_transaction_management = real_leave_transaction_management 61 76 transaction.managed = real_managed -
docs/ref/databases.txt
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index 2f55b9c..5a2042a 100644
a b currently the only engine that supports full-text indexing and searching. 142 142 The InnoDB_ engine is fully transactional and supports foreign key references 143 143 and is probably the best choice at this point in time. 144 144 145 .. versionchanged:: 1.4 146 147 In previous versions of Django, fixtures with forward references (i.e. 148 relations to rows that have not yet been inserted into the database) would fail 149 to load when using the InnoDB storage engine. This was due to the fact that InnoDB 150 deviates from the SQL standard by checking foreign key constraints immediately 151 instead of deferring the check until the transaction is committed. This 152 problem has been resolved in Django 1.4. Fixture data is now loaded with foreign key 153 checks turned off; foreign key checks are then re-enabled when the data has 154 finished loading, at which point the entire table is checked for invalid foreign 155 key references and an `IntegrityError` is raised if any are found. 156 145 157 .. _storage engines: http://dev.mysql.com/doc/refman/5.5/en/storage-engines.html 146 158 .. _MyISAM: http://dev.mysql.com/doc/refman/5.5/en/myisam-storage-engine.html 147 159 .. _InnoDB: http://dev.mysql.com/doc/refman/5.5/en/innodb.html -
tests/modeltests/serializers/tests.py
diff --git a/tests/modeltests/serializers/tests.py b/tests/modeltests/serializers/tests.py index 4a7e0a2..def0254 100644
a b 1 # This is necessary in Python 2.5 to enable the with statement, in 2.6 2 # and up it is no longer necessary. 3 from __future__ import with_statement 4 1 5 # -*- coding: utf-8 -*- 2 6 from datetime import datetime 3 7 from StringIO import StringIO … … from xml.dom import minidom 5 9 6 10 from django.conf import settings 7 11 from django.core import serializers 8 from django.db import transaction 12 from django.db import transaction, connection 9 13 from django.test import TestCase, TransactionTestCase, Approximate 10 14 from django.utils import simplejson, unittest 11 15 … … class SerializersTransactionTestBase(object): 252 256 transaction.enter_transaction_management() 253 257 transaction.managed(True) 254 258 objs = serializers.deserialize(self.serializer_name, self.fwd_ref_str) 255 for obj in objs: 256 obj.save() 259 with connection.constraint_checks_disabled(): 260 for obj in objs: 261 obj.save() 257 262 transaction.commit() 258 263 transaction.leave_transaction_management() 259 264 -
tests/regressiontests/backends/tests.py
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index 29db6a7..8adb40f 100644
a b 1 1 # -*- coding: utf-8 -*- 2 2 # Unit and doctests for specific database backends. 3 from __future__ import with_statement 3 4 import datetime 4 5 5 6 from django.conf import settings 6 7 from django.core.management.color import no_style 7 from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError 8 from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError, transaction 8 9 from django.db.backends.signals import connection_created 9 10 from django.db.backends.postgresql_psycopg2 import version as pg_version 10 11 from django.test import TestCase, skipUnlessDBFeature, TransactionTestCase … … class FkConstraintsTests(TransactionTestCase): 328 329 try: 329 330 a.save() 330 331 except IntegrityError: 331 pass 332 return 333 self.skipTest("This backend does not support integrity checks.") 332 334 333 335 def test_integrity_checks_on_update(self): 334 336 """ … … class FkConstraintsTests(TransactionTestCase): 343 345 try: 344 346 a.save() 345 347 except IntegrityError: 346 pass 348 return 349 self.skipTest("This backend does not support integrity checks.") 350 351 def test_disable_constraint_checks_manually(self): 352 """ 353 When constraint checks are disabled, should be able to write bad data without IntegrityErrors. 354 """ 355 with transaction.commit_manually(): 356 # Create an Article. 357 models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) 358 # Retrive it from the DB 359 a = models.Article.objects.get(headline="Test article") 360 a.reporter_id = 30 361 try: 362 connection.disable_constraint_checking() 363 a.save() 364 connection.enable_constraint_checking() 365 except IntegrityError: 366 self.fail("IntegrityError should not have occurred.") 367 finally: 368 transaction.rollback() 369 370 def test_disable_constraint_checks_context_manager(self): 371 """ 372 When constraint checks are disabled (using context manager), should be able to write bad data without IntegrityErrors. 373 """ 374 with transaction.commit_manually(): 375 # Create an Article. 376 models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) 377 # Retrive it from the DB 378 a = models.Article.objects.get(headline="Test article") 379 a.reporter_id = 30 380 try: 381 with connection.constraint_checks_disabled(): 382 a.save() 383 except IntegrityError: 384 self.fail("IntegrityError should not have occurred.") 385 finally: 386 transaction.rollback() 387 388 def test_check_constraints(self): 389 """ 390 Constraint checks should raise an IntegrityError when bad data is in the DB. 391 """ 392 with transaction.commit_manually(): 393 # Create an Article. 394 models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) 395 # Retrive it from the DB 396 a = models.Article.objects.get(headline="Test article") 397 a.reporter_id = 30 398 try: 399 with connection.constraint_checks_disabled(): 400 a.save() 401 with self.assertRaises(IntegrityError): 402 connection.check_constraints() 403 finally: 404 transaction.rollback() -
new file tests/regressiontests/fixtures_regress/fixtures/forward_ref.json
diff --git a/tests/regressiontests/fixtures_regress/fixtures/forward_ref.json b/tests/regressiontests/fixtures_regress/fixtures/forward_ref.json new file mode 100644 index 0000000..237b076
- + 1 [ 2 { 3 "pk": 1, 4 "model": "fixtures_regress.book", 5 "fields": { 6 "name": "Cryptonomicon", 7 "author": 4 8 } 9 }, 10 { 11 "pk": "4", 12 "model": "fixtures_regress.person", 13 "fields": { 14 "name": "Neal Stephenson" 15 } 16 } 17 ] 18 No newline at end of file -
new file tests/regressiontests/fixtures_regress/fixtures/forward_ref_bad_data.json
diff --git a/tests/regressiontests/fixtures_regress/fixtures/forward_ref_bad_data.json b/tests/regressiontests/fixtures_regress/fixtures/forward_ref_bad_data.json new file mode 100644 index 0000000..3a3fb64
- + 1 [ 2 { 3 "pk": 1, 4 "model": "fixtures_regress.book", 5 "fields": { 6 "name": "Cryptonomicon", 7 "author": 3 8 } 9 }, 10 { 11 "pk": "4", 12 "model": "fixtures_regress.person", 13 "fields": { 14 "name": "Neal Stephenson" 15 } 16 } 17 ] 18 No newline at end of file -
tests/regressiontests/fixtures_regress/tests.py
diff --git a/tests/regressiontests/fixtures_regress/tests.py b/tests/regressiontests/fixtures_regress/tests.py index a565ec9..344bc04 100644
a b class TestFixtures(TestCase): 361 361 """[{"pk": %d, "model": "fixtures_regress.widget", "fields": {"name": "grommet"}}]""" 362 362 % widget.pk 363 363 ) 364 365 def test_loaddata_works_when_fixture_has_forward_refs(self): 366 """ 367 Regression for #3615 - Forward references cause fixtures not to load in MySQL (InnoDB) 368 """ 369 management.call_command( 370 'loaddata', 371 'forward_ref.json', 372 verbosity=0, 373 commit=False 374 ) 375 self.assertEqual(Book.objects.all()[0].id, 1) 376 self.assertEqual(Person.objects.all()[0].id, 4) 377 378 def test_loaddata_raises_error_when_fixture_has_invalid_foreign_key(self): 379 """ 380 Regression for #3615 - Ensure data with nonexistent child key references raises error 381 """ 382 stderr = StringIO() 383 management.call_command( 384 'loaddata', 385 'forward_ref_bad_data.json', 386 verbosity=0, 387 commit=False, 388 stderr=stderr, 389 ) 390 self.assertTrue( 391 stderr.getvalue().startswith('Problem installing fixture') 392 ) 364 393 365 394 366 395 class NaturalKeyFixtureTests(TestCase): -
tests/regressiontests/introspection/tests.py
diff --git a/tests/regressiontests/introspection/tests.py b/tests/regressiontests/introspection/tests.py index 4f5fb09..a7c5bf2 100644
a b class IntrospectionTests(TestCase): 95 95 # That's {field_index: (field_index_other_table, other_table)} 96 96 self.assertEqual(relations, {3: (0, Reporter._meta.db_table)}) 97 97 98 def test_get_key_columns(self): 99 cursor = connection.cursor() 100 key_columns = connection.introspection.get_key_columns(cursor, Article._meta.db_table) 101 self.assertEqual(key_columns, [(u'reporter_id', Reporter._meta.db_table, u'id')]) 102 103 def test_get_primary_key_column(self): 104 cursor = connection.cursor() 105 primary_key_column = connection.introspection.get_primary_key_column(cursor, Article._meta.db_table) 106 self.assertEqual(primary_key_column, u'id') 107 98 108 def test_get_indexes(self): 99 109 cursor = connection.cursor() 100 110 indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) -
tests/regressiontests/serializers_regress/tests.py
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index cd2ce3c..bb6f598 100644
a b test case that is capable of testing the capabilities of 6 6 the serializers. This includes all valid data values, plus 7 7 forward, backwards and self references. 8 8 """ 9 # This is necessary in Python 2.5 to enable the with statement, in 2.6 10 # and up it is no longer necessary. 9 11 from __future__ import with_statement 10 12 11 13 import datetime … … def serializerTest(format, self): 382 384 objects = [] 383 385 instance_count = {} 384 386 for (func, pk, klass, datum) in test_data: 385 objects.extend(func[0](pk, klass, datum)) 387 with connection.constraint_checks_disabled(): 388 objects.extend(func[0](pk, klass, datum)) 386 389 387 390 # Get a count of the number of objects created for each class 388 391 for klass in instance_count: -
tests/regressiontests/test_utils/models.py
diff --git a/tests/regressiontests/test_utils/models.py b/tests/regressiontests/test_utils/models.py index 4da7a07..7a7a94e 100644
a b from django.db import models 3 3 4 4 class Person(models.Model): 5 5 name = models.CharField(max_length=100) 6 7 class Pet(models.Model): 8 name = models.CharField(max_length=100) 9 owner = models.ForeignKey(Person) 10 11 def __unicode__(self): 12 return self.name 13 14 class Meta: 15 ordering = ('name',) -
tests/regressiontests/test_utils/tests.py
diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py index a35b0bc..72a0e51 100644
a b from __future__ import with_statement 2 2 3 3 from django.test import TestCase, skipUnlessDBFeature 4 4 from django.utils.unittest import skip 5 from django.db import IntegrityError 5 6 6 from models import Person 7 from models import Person, Pet 7 8 8 9 9 10 class SkippingTestCase(TestCase): … … class AssertNumQueriesContextManagerTests(TestCase): 86 87 self.client.get("/test_utils/get_person/%s/" % person.pk) 87 88 88 89 90 class TransactionPatchingTests(TestCase): 91 def test_bad_data_should_raise_data_integrity_error(self): 92 """ 93 Ensure bad data cannot be saved to DB during tests. 94 """ 95 bill = Person.objects.create(name="Bill") 96 dog = Pet.objects.create(name="Spot", owner=bill) 97 dog.owner_id = 20 # Does not exist 98 with self.assertRaises(IntegrityError): 99 dog.save() 100 89 101 class SaveRestoreWarningState(TestCase): 90 102 def test_save_restore_warnings_state(self): 91 103 """