Simplified schema.tests with assertForeignKeyExists()/assertForeignKeyNotExists().

Thanks Tim Graham for the review.
This commit is contained in:
Mariusz Felisiak 2017-05-24 16:43:56 +02:00 committed by GitHub
parent cb16458c4f
commit 663d1c3160
1 changed files with 39 additions and 131 deletions

View File

@ -173,6 +173,23 @@ class SchemaTests(TransactionTestCase):
index_orders = constraints[index]['orders'] index_orders = constraints[index]['orders']
self.assertTrue(all([(val == expected) for val, expected in zip(index_orders, order)])) self.assertTrue(all([(val == expected) for val, expected in zip(index_orders, order)]))
def assertForeignKeyExists(self, model, column, expected_fk_table):
"""
Fail if the FK constraint on `model.Meta.db_table`.`column` to
`expected_fk_table`.id doesn't exist.
"""
constraints = self.get_constraints(model._meta.db_table)
constraint_fk = None
for name, details in constraints.items():
if details['columns'] == [column] and details['foreign_key']:
constraint_fk = details['foreign_key']
break
self.assertEqual(constraint_fk, (expected_fk_table, 'id'))
def assertForeignKeyNotExists(self, model, column, expected_fk_table):
with self.assertRaises(AssertionError):
self.assertForeignKeyExists(model, column, expected_fk_table)
# Tests # Tests
def test_creation_deletion(self): def test_creation_deletion(self):
""" """
@ -214,14 +231,7 @@ class SchemaTests(TransactionTestCase):
new_field.set_attributes_from_name("author") new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.alter_field(Book, old_field, new_field, strict=True) editor.alter_field(Book, old_field, new_field, strict=True)
# Make sure the new FK constraint is present self.assertForeignKeyExists(Book, 'author_id', 'schema_tag')
constraints = self.get_constraints(Book._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["author_id"] and details['foreign_key']:
self.assertEqual(details['foreign_key'], ('schema_tag', 'id'))
break
else:
self.fail("No FK constraint for author_id found")
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_char_field_with_db_index_to_fk(self): def test_char_field_with_db_index_to_fk(self):
@ -235,14 +245,7 @@ class SchemaTests(TransactionTestCase):
new_field.set_attributes_from_name('char_field') new_field.set_attributes_from_name('char_field')
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.alter_field(AuthorCharFieldWithIndex, old_field, new_field, strict=True) editor.alter_field(AuthorCharFieldWithIndex, old_field, new_field, strict=True)
# The new FK constraint is present self.assertForeignKeyExists(AuthorCharFieldWithIndex, 'char_field_id', 'schema_author')
constraints = self.get_constraints(AuthorCharFieldWithIndex._meta.db_table)
constraint_fk = None
for name, details in constraints.items():
if details['columns'] == ['char_field_id'] and details['foreign_key']:
constraint_fk = details['foreign_key']
break
self.assertEqual(constraint_fk, ('schema_author', 'id'))
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
@skipUnlessDBFeature('supports_index_on_text_field') @skipUnlessDBFeature('supports_index_on_text_field')
@ -257,14 +260,7 @@ class SchemaTests(TransactionTestCase):
new_field.set_attributes_from_name('text_field') new_field.set_attributes_from_name('text_field')
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.alter_field(AuthorTextFieldWithIndex, old_field, new_field, strict=True) editor.alter_field(AuthorTextFieldWithIndex, old_field, new_field, strict=True)
# The new FK constraint is present self.assertForeignKeyExists(AuthorTextFieldWithIndex, 'text_field_id', 'schema_author')
constraints = self.get_constraints(AuthorTextFieldWithIndex._meta.db_table)
constraint_fk = None
for name, details in constraints.items():
if details['columns'] == ['text_field_id'] and details['foreign_key']:
constraint_fk = details['foreign_key']
break
self.assertEqual(constraint_fk, ('schema_author', 'id'))
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_fk_to_proxy(self): def test_fk_to_proxy(self):
@ -288,13 +284,7 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.create_model(Author) editor.create_model(Author)
editor.create_model(AuthorRef) editor.create_model(AuthorRef)
constraints = self.get_constraints(AuthorRef._meta.db_table) self.assertForeignKeyExists(AuthorRef, 'author_id', 'schema_author')
for details in constraints.values():
if details['columns'] == ['author_id'] and details['foreign_key']:
self.assertEqual(details['foreign_key'], ('schema_author', 'id'))
break
else:
self.fail('No FK constraint for author_id found')
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_fk_db_constraint(self): def test_fk_db_constraint(self):
@ -308,44 +298,25 @@ class SchemaTests(TransactionTestCase):
list(Author.objects.all()) list(Author.objects.all())
list(Tag.objects.all()) list(Tag.objects.all())
list(BookWeak.objects.all()) list(BookWeak.objects.all())
# BookWeak doesn't have an FK constraint self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
constraints = self.get_constraints(BookWeak._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["author_id"] and details['foreign_key']:
self.fail("FK constraint for author_id found")
# Make a db_constraint=False FK # Make a db_constraint=False FK
new_field = ForeignKey(Tag, CASCADE, db_constraint=False) new_field = ForeignKey(Tag, CASCADE, db_constraint=False)
new_field.set_attributes_from_name("tag") new_field.set_attributes_from_name("tag")
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.add_field(Author, new_field) editor.add_field(Author, new_field)
# No FK constraint is present self.assertForeignKeyNotExists(Author, 'tag_id', 'schema_tag')
constraints = self.get_constraints(Author._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["tag_id"] and details['foreign_key']:
self.fail("FK constraint for tag_id found")
# Alter to one with a constraint # Alter to one with a constraint
new_field2 = ForeignKey(Tag, CASCADE) new_field2 = ForeignKey(Tag, CASCADE)
new_field2.set_attributes_from_name("tag") new_field2.set_attributes_from_name("tag")
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, new_field2, strict=True) editor.alter_field(Author, new_field, new_field2, strict=True)
# The new FK constraint is present self.assertForeignKeyExists(Author, 'tag_id', 'schema_tag')
constraints = self.get_constraints(Author._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["tag_id"] and details['foreign_key']:
self.assertEqual(details['foreign_key'], ('schema_tag', 'id'))
break
else:
self.fail("No FK constraint for tag_id found")
# Alter to one without a constraint again # Alter to one without a constraint again
new_field2 = ForeignKey(Tag, CASCADE) new_field2 = ForeignKey(Tag, CASCADE)
new_field2.set_attributes_from_name("tag") new_field2.set_attributes_from_name("tag")
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.alter_field(Author, new_field2, new_field, strict=True) editor.alter_field(Author, new_field2, new_field, strict=True)
# No FK constraint is present self.assertForeignKeyNotExists(Author, 'tag_id', 'schema_tag')
constraints = self.get_constraints(Author._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["tag_id"] and details['foreign_key']:
self.fail("FK constraint for tag_id found")
def _test_m2m_db_constraint(self, M2MFieldClass): def _test_m2m_db_constraint(self, M2MFieldClass):
class LocalAuthorWithM2M(Model): class LocalAuthorWithM2M(Model):
@ -370,11 +341,7 @@ class SchemaTests(TransactionTestCase):
# Add the field # Add the field
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.add_field(LocalAuthorWithM2M, new_field) editor.add_field(LocalAuthorWithM2M, new_field)
# No FK constraint is present self.assertForeignKeyNotExists(new_field.remote_field.through, 'tag_id', 'schema_tag')
constraints = self.get_constraints(new_field.remote_field.through._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["tag_id"] and details['foreign_key']:
self.fail("FK constraint for tag_id found")
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_m2m_db_constraint(self): def test_m2m_db_constraint(self):
@ -768,14 +735,7 @@ class SchemaTests(TransactionTestCase):
# Ensure the field is right to begin with # Ensure the field is right to begin with
columns = self.column_classes(Book) columns = self.column_classes(Book)
self.assertEqual(columns['author_id'][0], "IntegerField") self.assertEqual(columns['author_id'][0], "IntegerField")
# Make sure the FK constraint is present self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
constraints = self.get_constraints(Book._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["author_id"] and details['foreign_key']:
self.assertEqual(details['foreign_key'], ('schema_author', 'id'))
break
else:
self.fail("No FK constraint for author_id found")
# Alter the FK # Alter the FK
old_field = Book._meta.get_field("author") old_field = Book._meta.get_field("author")
new_field = ForeignKey(Author, CASCADE, editable=False) new_field = ForeignKey(Author, CASCADE, editable=False)
@ -785,14 +745,7 @@ class SchemaTests(TransactionTestCase):
# Ensure the field is right afterwards # Ensure the field is right afterwards
columns = self.column_classes(Book) columns = self.column_classes(Book)
self.assertEqual(columns['author_id'][0], "IntegerField") self.assertEqual(columns['author_id'][0], "IntegerField")
# Make sure the FK constraint is present self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
constraints = self.get_constraints(Book._meta.db_table)
for name, details in constraints.items():
if details['columns'] == ["author_id"] and details['foreign_key']:
self.assertEqual(details['foreign_key'], ('schema_author', 'id'))
break
else:
self.fail("No FK constraint for author_id found")
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_alter_to_fk(self): def test_alter_to_fk(self):
@ -824,14 +777,7 @@ class SchemaTests(TransactionTestCase):
new_field.set_attributes_from_name("author") new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
editor.alter_field(LocalBook, old_field, new_field, strict=True) editor.alter_field(LocalBook, old_field, new_field, strict=True)
constraints = self.get_constraints(LocalBook._meta.db_table) self.assertForeignKeyExists(LocalBook, 'author_id', 'schema_author')
# Ensure FK constraint exists
for name, details in constraints.items():
if details['foreign_key'] and details['columns'] == ["author_id"]:
self.assertEqual(details['foreign_key'], ('schema_author', 'id'))
break
else:
self.fail("No FK constraint for author_id found")
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_alter_o2o_to_fk(self): def test_alter_o2o_to_fk(self):
@ -851,14 +797,7 @@ class SchemaTests(TransactionTestCase):
with self.assertRaises(IntegrityError): with self.assertRaises(IntegrityError):
BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now()) BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
BookWithO2O.objects.all().delete() BookWithO2O.objects.all().delete()
# Make sure the FK constraint is present self.assertForeignKeyExists(BookWithO2O, 'author_id', 'schema_author')
constraints = self.get_constraints(BookWithO2O._meta.db_table)
author_is_fk = False
for name, details in constraints.items():
if details['columns'] == ['author_id']:
if details['foreign_key'] and details['foreign_key'] == ('schema_author', 'id'):
author_is_fk = True
self.assertTrue(author_is_fk, "No FK constraint for author_id found")
# Alter the OneToOneField to ForeignKey # Alter the OneToOneField to ForeignKey
old_field = BookWithO2O._meta.get_field("author") old_field = BookWithO2O._meta.get_field("author")
new_field = ForeignKey(Author, CASCADE) new_field = ForeignKey(Author, CASCADE)
@ -871,14 +810,7 @@ class SchemaTests(TransactionTestCase):
# Ensure the field is not unique anymore # Ensure the field is not unique anymore
Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now()) Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
# Make sure the FK constraint is still present self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
constraints = self.get_constraints(Book._meta.db_table)
author_is_fk = False
for name, details in constraints.items():
if details['columns'] == ['author_id']:
if details['foreign_key'] and details['foreign_key'] == ('schema_author', 'id'):
author_is_fk = True
self.assertTrue(author_is_fk, "No FK constraint for author_id found")
@skipUnlessDBFeature('supports_foreign_keys') @skipUnlessDBFeature('supports_foreign_keys')
def test_alter_fk_to_o2o(self): def test_alter_fk_to_o2o(self):
@ -897,14 +829,7 @@ class SchemaTests(TransactionTestCase):
Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now()) Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
Book.objects.all().delete() Book.objects.all().delete()
# Make sure the FK constraint is present self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
constraints = self.get_constraints(Book._meta.db_table)
author_is_fk = False
for name, details in constraints.items():
if details['columns'] == ['author_id']:
if details['foreign_key'] and details['foreign_key'] == ('schema_author', 'id'):
author_is_fk = True
self.assertTrue(author_is_fk, "No FK constraint for author_id found")
# Alter the ForeignKey to OneToOneField # Alter the ForeignKey to OneToOneField
old_field = Book._meta.get_field("author") old_field = Book._meta.get_field("author")
new_field = OneToOneField(Author, CASCADE) new_field = OneToOneField(Author, CASCADE)
@ -918,14 +843,7 @@ class SchemaTests(TransactionTestCase):
BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
with self.assertRaises(IntegrityError): with self.assertRaises(IntegrityError):
BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now()) BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
# Make sure the FK constraint is present self.assertForeignKeyExists(BookWithO2O, 'author_id', 'schema_author')
constraints = self.get_constraints(BookWithO2O._meta.db_table)
author_is_fk = False
for name, details in constraints.items():
if details['columns'] == ['author_id']:
if details['foreign_key'] and details['foreign_key'] == ('schema_author', 'id'):
author_is_fk = True
self.assertTrue(author_is_fk, "No FK constraint for author_id found")
def test_alter_field_fk_to_o2o(self): def test_alter_field_fk_to_o2o(self):
with connection.schema_editor() as editor: with connection.schema_editor() as editor:
@ -1363,16 +1281,12 @@ class SchemaTests(TransactionTestCase):
editor.create_model(TagM2MTest) editor.create_model(TagM2MTest)
editor.create_model(UniqueTest) editor.create_model(UniqueTest)
# Ensure the M2M exists and points to TagM2MTest # Ensure the M2M exists and points to TagM2MTest
constraints = self.get_constraints(
LocalBookWithM2M._meta.get_field("tags").remote_field.through._meta.db_table
)
if connection.features.supports_foreign_keys: if connection.features.supports_foreign_keys:
for name, details in constraints.items(): self.assertForeignKeyExists(
if details['columns'] == ["tagm2mtest_id"] and details['foreign_key']: LocalBookWithM2M._meta.get_field("tags").remote_field.through,
self.assertEqual(details['foreign_key'], ('schema_tagm2mtest', 'id')) 'tagm2mtest_id',
break 'schema_tagm2mtest',
else: )
self.fail("No FK constraint for tagm2mtest_id found")
# Repoint the M2M # Repoint the M2M
old_field = LocalBookWithM2M._meta.get_field("tags") old_field = LocalBookWithM2M._meta.get_field("tags")
new_field = M2MFieldClass(UniqueTest) new_field = M2MFieldClass(UniqueTest)
@ -1387,14 +1301,8 @@ class SchemaTests(TransactionTestCase):
opts = LocalBookWithM2M._meta opts = LocalBookWithM2M._meta
opts.local_many_to_many.remove(old_field) opts.local_many_to_many.remove(old_field)
# Ensure the new M2M exists and points to UniqueTest # Ensure the new M2M exists and points to UniqueTest
constraints = self.get_constraints(new_field.remote_field.through._meta.db_table)
if connection.features.supports_foreign_keys: if connection.features.supports_foreign_keys:
for name, details in constraints.items(): self.assertForeignKeyExists(new_field.remote_field.through, 'uniquetest_id', 'schema_uniquetest')
if details['columns'] == ["uniquetest_id"] and details['foreign_key']:
self.assertEqual(details['foreign_key'], ('schema_uniquetest', 'id'))
break
else:
self.fail("No FK constraint for uniquetest_id found")
def test_m2m_repoint(self): def test_m2m_repoint(self):
self._test_m2m_repoint(ManyToManyField) self._test_m2m_repoint(ManyToManyField)