def test_no_index_for_foreignkey(self): """ MySQL on InnoDB already creates indexes automatically for foreign keys. (#14180). An index should be created if db_constraint=False (#26171). """ storage = connection.introspection.get_storage_engine( connection.cursor(), ArticleTranslation._meta.db_table) if storage != "InnoDB": self.skip("This test only applies to the InnoDB storage engine") index_sql = connection.schema_editor()._model_indexes_sql( ArticleTranslation) self.assertEqual(index_sql, [ 'CREATE INDEX `indexes_articletranslation_article_no_constraint_id_d6c0806b` ' 'ON `indexes_articletranslation` (`article_no_constraint_id`)' ]) # The index also shouldn't be created if the ForeignKey is added after # the model was created. field_created = False try: with connection.schema_editor() as editor: new_field = ForeignKey(Article, CASCADE) new_field.set_attributes_from_name('new_foreign_key') editor.add_field(ArticleTranslation, new_field) field_created = True self.assertEqual(editor.deferred_sql, [ 'ALTER TABLE `indexes_articletranslation` ' 'ADD CONSTRAINT `indexes_articletrans_new_foreign_key_id_d27a9146_fk_indexes_a` ' 'FOREIGN KEY (`new_foreign_key_id`) REFERENCES `indexes_article` (`id`)' ]) finally: if field_created: with connection.schema_editor() as editor: editor.remove_field(ArticleTranslation, new_field)
def test_fk(self): "Tests that creating tables out of FK order, then repointing, works" # Create the table with connection.schema_editor() as editor: editor.create_model(Book) editor.create_model(Author) editor.create_model(Tag) # Check that initial tables are there list(Author.objects.all()) list(Book.objects.all()) # Make sure the FK constraint is present with self.assertRaises(IntegrityError): Book.objects.create( author_id=1, title="Much Ado About Foreign Keys", pub_date=datetime.datetime.now(), ) # Repoint the FK constraint new_field = ForeignKey(Tag) new_field.set_attributes_from_name("author") with connection.schema_editor() as editor: editor.alter_field( Book, Book._meta.get_field_by_name("author")[0], new_field, strict=True, ) # Make sure the new FK constraint is present 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")
def test_no_index_for_foreignkey(self): """ MySQL on InnoDB already creates indexes automatically for foreign keys. (#14180). An index should be created if db_constraint=False (#26171). """ storage = connection.introspection.get_storage_engine( connection.cursor(), ArticleTranslation._meta.db_table ) if storage != "InnoDB": self.skip("This test only applies to the InnoDB storage engine") index_sql = connection.schema_editor()._model_indexes_sql(ArticleTranslation) self.assertEqual(index_sql, [ 'CREATE INDEX `indexes_articletranslation_article_no_constraint_id_d6c0806b` ' 'ON `indexes_articletranslation` (`article_no_constraint_id`)' ]) # The index also shouldn't be created if the ForeignKey is added after # the model was created. with connection.schema_editor() as editor: new_field = ForeignKey(Article, CASCADE) new_field.set_attributes_from_name('new_foreign_key') editor.add_field(ArticleTranslation, new_field) self.assertEqual(editor.deferred_sql, [ 'ALTER TABLE `indexes_articletranslation` ' 'ADD CONSTRAINT `indexes_articletrans_new_foreign_key_id_d27a9146_fk_indexes_a` ' 'FOREIGN KEY (`new_foreign_key_id`) REFERENCES `indexes_article` (`id`)' ])
def test_no_index_for_foreignkey(self): """ MySQL on InnoDB already creates indexes automatically for foreign keys. (#14180). An index should be created if db_constraint=False (#26171). """ storage = connection.introspection.get_storage_engine( connection.cursor(), ArticleTranslation._meta.db_table ) if storage != "InnoDB": self.skip("This test only applies to the InnoDB storage engine") index_sql = [str(statement) for statement in connection.schema_editor()._model_indexes_sql(ArticleTranslation)] self.assertEqual(index_sql, [ 'CREATE INDEX `indexes_articletranslation_article_no_constraint_id_d6c0806b` ' 'ON `indexes_articletranslation` (`article_no_constraint_id`)' ]) # The index also shouldn't be created if the ForeignKey is added after # the model was created. field_created = False try: with connection.schema_editor() as editor: new_field = ForeignKey(Article, CASCADE) new_field.set_attributes_from_name('new_foreign_key') editor.add_field(ArticleTranslation, new_field) field_created = True # No deferred SQL. The FK constraint is included in the # statement to add the field. self.assertFalse(editor.deferred_sql) finally: if field_created: with connection.schema_editor() as editor: editor.remove_field(ArticleTranslation, new_field)
def test_alter_fk(self): """ Tests altering of FKs """ # Create the table with connection.schema_editor() as editor: editor.create_model(Author) editor.create_model(Book) # Ensure the field is right to begin with columns = self.column_classes(Book) self.assertEqual(columns["author_id"][0], "IntegerField") # Make sure the FK constraint is present 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 new_field = ForeignKey(Author, editable=False) new_field.set_attributes_from_name("author") with connection.schema_editor() as editor: editor.alter_field(Book, Book._meta.get_field_by_name("author")[0], new_field, strict=True) # Ensure the field is right afterwards columns = self.column_classes(Book) self.assertEqual(columns["author_id"][0], "IntegerField") # Make sure the FK constraint is present 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")
def test_fk_index_creation(self): new_field = ForeignKey(Foo) new_field.set_attributes_from_name(None) with connection.schema_editor() as editor: editor.add_field(Bar, new_field) # Just return indexes others that not automaically created by Fk indexes = editor._get_field_indexes(Bar, new_field) self.assertEqual(indexes, [])
def test_fk_index_creation(self): new_field = ForeignKey(Foo) new_field.set_attributes_from_name(None) with connection.schema_editor() as editor: editor.add_field( Bar, new_field ) # Just return indexes others that not automaically created by Fk indexes = editor._get_field_indexes(Bar, new_field) self.assertEqual(indexes, [])
def test_add_foreign_key_long_names(self): """ Regression test for #23009. Only affects databases that supports foreign keys. """ # Create the initial tables with connection.schema_editor() as editor: editor.create_model(AuthorWithEvenLongerName) editor.create_model(BookWithLongName) # Add a second FK, this would fail due to long ref name before the fix new_field = ForeignKey(AuthorWithEvenLongerName, related_name="something") new_field.set_attributes_from_name("author_other_really_long_named_i_mean_so_long_fk") with connection.schema_editor() as editor: editor.add_field(BookWithLongName, new_field)
def test_add_foreign_key_long_names(self): """ Regression test for #23009. Only affects databases that supports foreign keys. """ # Create the initial tables with connection.schema_editor() as editor: editor.create_model(AuthorWithEvenLongerName) editor.create_model(BookWithLongName) # Add a second FK, this would fail due to long ref name before the fix new_field = ForeignKey(AuthorWithEvenLongerName, related_name="something") new_field.set_attributes_from_name("author_other_really_long_named_i_mean_so_long_fk") with connection.schema_editor() as editor: editor.add_field( BookWithLongName, new_field, )
def test_alter_fk(self): """ Tests altering of FKs """ # Create the table with connection.schema_editor() as editor: editor.create_model(Author) editor.create_model(Book) # Ensure the field is right to begin with columns = self.column_classes(Book) self.assertEqual(columns['author_id'][0], "IntegerField") # Make sure the FK constraint is present 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 new_field = ForeignKey(Author, editable=False) new_field.set_attributes_from_name("author") with connection.schema_editor() as editor: editor.alter_field( Book, Book._meta.get_field_by_name("author")[0], new_field, strict=True, ) # Ensure the field is right afterwards columns = self.column_classes(Book) self.assertEqual(columns['author_id'][0], "IntegerField") # Make sure the FK constraint is present 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")
def test_fk_db_constraint(self): "Tests that the db_constraint parameter is respected" # Create the table with connection.schema_editor() as editor: editor.create_model(Tag) editor.create_model(Author) editor.create_model(BookWeak) # Check that initial tables are there list(Author.objects.all()) list(Tag.objects.all()) list(BookWeak.objects.all()) # Check that BookWeak doesn't have an FK constraint 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 new_field = ForeignKey(Tag, db_constraint=False) new_field.set_attributes_from_name("tag") with connection.schema_editor() as editor: editor.add_field(Author, new_field) # Make sure no FK constraint is present 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 new_field_2 = ForeignKey(Tag) new_field_2.set_attributes_from_name("tag") with connection.schema_editor() as editor: editor.alter_field(Author, new_field, new_field_2, strict=True) # Make sure the new FK constraint is present 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 new_field_2 = ForeignKey(Tag) new_field_2.set_attributes_from_name("tag") with connection.schema_editor() as editor: editor.alter_field(Author, new_field_2, new_field, strict=True) # Make sure no FK constraint is present 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_fk_db_constraint(self): "Tests that the db_constraint parameter is respected" # Create the table with connection.schema_editor() as editor: editor.create_model(Tag) editor.create_model(Author) editor.create_model(BookWeak) # Check that initial tables are there list(Author.objects.all()) list(Tag.objects.all()) list(BookWeak.objects.all()) # Check that BookWeak doesn't have an FK constraint 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 new_field = ForeignKey(Tag, db_constraint=False) new_field.set_attributes_from_name("tag") with connection.schema_editor() as editor: editor.add_field( Author, new_field, ) # Make sure no FK constraint is present 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 new_field_2 = ForeignKey(Tag) new_field_2.set_attributes_from_name("tag") with connection.schema_editor() as editor: editor.alter_field( Author, new_field, new_field_2, strict=True, ) # Make sure the new FK constraint is present 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 new_field_2 = ForeignKey(Tag) new_field_2.set_attributes_from_name("tag") with connection.schema_editor() as editor: editor.alter_field( Author, new_field_2, new_field, strict=True, ) # Make sure no FK constraint is present 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")