diff options
| author | Ben Cail <bcail@crossway.org> | 2024-02-01 16:08:42 -0500 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2024-07-30 17:27:10 +0200 |
| commit | 9cf9c796be8dd53bc3b11355ff39d65c81d7be6d (patch) | |
| tree | 3d5e2c2a4bd8cdac02f079b2a62135e575f19687 /tests/schema | |
| parent | 7e00fee3bd3b780667f072325bdb69f29144c553 (diff) | |
Fixed #28646 -- Prevented duplicate index when unique is set to True on PostgreSQL.
Diffstat (limited to 'tests/schema')
| -rw-r--r-- | tests/schema/models.py | 14 | ||||
| -rw-r--r-- | tests/schema/tests.py | 211 |
2 files changed, 225 insertions, 0 deletions
diff --git a/tests/schema/models.py b/tests/schema/models.py index 75e32a0eab..2fc9095b61 100644 --- a/tests/schema/models.py +++ b/tests/schema/models.py @@ -147,6 +147,20 @@ class IntegerPK(models.Model): db_table = "INTEGERPK" # uppercase to ensure proper quoting +class CharFieldPK(models.Model): + field1 = models.CharField(max_length=10, primary_key=True) + + class Meta: + apps = new_apps + + +class CharFieldPKUnique(models.Model): + field1 = models.CharField(max_length=10, primary_key=True, unique=True) + + class Meta: + apps = new_apps + + class Note(models.Model): info = models.TextField() address = models.TextField(null=True) diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 3a2947cf43..88e346e923 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -86,6 +86,8 @@ from .models import ( BookWithO2O, BookWithoutAuthor, BookWithSlug, + CharFieldPK, + CharFieldPKUnique, IntegerPK, Node, Note, @@ -121,6 +123,8 @@ class SchemaTests(TransactionTestCase): BookWithLongName, BookWithO2O, BookWithSlug, + CharFieldPK, + CharFieldPKUnique, IntegerPK, Node, Note, @@ -5210,6 +5214,213 @@ class SchemaTests(TransactionTestCase): ["schema_tag_slug_2c418ba3_like", "schema_tag_slug_key"], ) + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_charfield_primary_key_to_db_index(self): + # Create the table and verify initial indexes. + with connection.schema_editor() as editor: + editor.create_model(CharFieldPK) + self.assertEqual( + self.get_constraints_for_column(CharFieldPK, "field1"), + ["schema_charfieldpk_field1_0eb93b91_like", "schema_charfieldpk_pkey"], + ) + # Alter to remove primary_key and set db_index=True. + old_field1 = CharFieldPK._meta.get_field("field1") + new_field1 = CharField(db_index=True, primary_key=False) + new_field1.set_attributes_from_name("field1") + with connection.schema_editor() as editor: + editor.alter_field(CharFieldPK, old_field1, new_field1, strict=True) + self.assertEqual( + self.get_constraints_for_column(CharFieldPK, "field1"), + [ + "schema_charfieldpk_field1_0eb93b91", + "schema_charfieldpk_field1_0eb93b91_like", + ], + ) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_charfield_primary_key_to_unique(self): + # Create the table and verify initial indexes. + with connection.schema_editor() as editor: + editor.create_model(CharFieldPK) + self.assertEqual( + self.get_constraints_for_column(CharFieldPK, "field1"), + ["schema_charfieldpk_field1_0eb93b91_like", "schema_charfieldpk_pkey"], + ) + # Alter to remove primary_key and set unique=True. + old_field1 = CharFieldPK._meta.get_field("field1") + new_field1 = CharField(unique=True, primary_key=False) + new_field1.set_attributes_from_name("field1") + new_field1.model = CharFieldPK + with connection.schema_editor() as editor: + editor.alter_field(CharFieldPK, old_field1, new_field1, strict=True) + self.assertEqual( + self.get_constraints_for_column(CharFieldPK, "field1"), + [ + "schema_charfieldpk_field1_0eb93b91_like", + "schema_charfieldpk_field1_0eb93b91_uniq", + ], + ) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_charfield_primary_key_to_db_index_and_unique(self): + # Create the table and verify initial indexes. + with connection.schema_editor() as editor: + editor.create_model(CharFieldPK) + self.assertEqual( + self.get_constraints_for_column(CharFieldPK, "field1"), + ["schema_charfieldpk_field1_0eb93b91_like", "schema_charfieldpk_pkey"], + ) + # Alter to remove primary_key and set db_index=True and unique=True. + old_field1 = CharFieldPK._meta.get_field("field1") + new_field1 = CharField(unique=True, db_index=True, primary_key=False) + new_field1.set_attributes_from_name("field1") + new_field1.model = CharFieldPK + with connection.schema_editor() as editor: + editor.alter_field(CharFieldPK, old_field1, new_field1, strict=True) + self.assertEqual( + self.get_constraints_for_column(CharFieldPK, "field1"), + [ + "schema_charfieldpk_field1_0eb93b91_like", + "schema_charfieldpk_field1_0eb93b91_uniq", + ], + ) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_charfield_primary_key_unique_to_just_unique(self): + # Create the table and verify initial indexes. + with connection.schema_editor() as editor: + editor.create_model(CharFieldPKUnique) + self.assertEqual( + self.get_constraints_for_column(CharFieldPKUnique, "field1"), + [ + "schema_charfieldpkunique_field1_ffc9a22c_like", + "schema_charfieldpkunique_pkey", + ], + ) + # Alter to remove primary_key (but still unique). + old_field1 = CharFieldPKUnique._meta.get_field("field1") + new_field1 = CharField(unique=True, primary_key=False) + new_field1.set_attributes_from_name("field1") + new_field1.model = CharFieldPKUnique + with connection.schema_editor() as editor: + editor.alter_field(CharFieldPKUnique, old_field1, new_field1, strict=True) + self.assertEqual( + self.get_constraints_for_column(CharFieldPKUnique, "field1"), + [ + "schema_charfieldpkunique_field1_ffc9a22c_like", + "schema_charfieldpkunique_field1_ffc9a22c_uniq", + ], + ) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_charfield_db_index_to_textfield_db_index(self): + with connection.schema_editor() as editor: + editor.create_model(AuthorCharFieldWithIndex) + self.assertEqual( + self.get_constraints_for_column(AuthorCharFieldWithIndex, "char_field"), + [ + "schema_authorcharfieldwithindex_char_field_06a11776", + "schema_authorcharfieldwithindex_char_field_06a11776_like", + ], + ) + old_field = AuthorCharFieldWithIndex._meta.get_field("char_field") + new_field = TextField(db_index=True) + new_field.set_attributes_from_name("char_field") + new_field.model = AuthorCharFieldWithIndex + with connection.schema_editor() as editor: + editor.alter_field( + AuthorCharFieldWithIndex, old_field, new_field, strict=True + ) + self.assertEqual( + self.get_constraints_for_column(AuthorCharFieldWithIndex, "char_field"), + [ + "schema_authorcharfieldwithindex_char_field_06a11776", + "schema_authorcharfieldwithindex_char_field_06a11776_like", + ], + ) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_charfield_change_max_length_no_index_created(self): + with connection.schema_editor() as editor: + editor.create_model(Author) + self.assertEqual( + self.get_constraints_for_column(Author, "name"), + [], + ) + old_name = Author._meta.get_field("name") + new_name = CharField(max_length=20) + new_name.set_attributes_from_name("name") + with connection.schema_editor() as editor: + editor.alter_field(Author, old_name, new_name, strict=True) + self.assertEqual( + self.get_constraints_for_column(Author, "name"), + [], + ) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_remove_db_index(self): + with connection.schema_editor() as editor: + editor.create_model(AuthorCharFieldWithIndex) + self.assertEqual( + self.get_constraints_for_column(AuthorCharFieldWithIndex, "char_field"), + [ + "schema_authorcharfieldwithindex_char_field_06a11776", + "schema_authorcharfieldwithindex_char_field_06a11776_like", + ], + ) + old_char_field = AuthorCharFieldWithIndex._meta.get_field("char_field") + new_char_field = CharField(max_length=31, db_index=False) + new_char_field.set_attributes_from_name("char_field") + with connection.schema_editor() as editor: + editor.alter_field( + AuthorCharFieldWithIndex, old_char_field, new_char_field, strict=True + ) + self.assertEqual( + self.get_constraints_for_column(AuthorCharFieldWithIndex, "char_field"), + [], + ) + + @isolate_apps("schema") + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + def test_slugfields_change_primary_key(self): + class SimpleModel(Model): + field1 = SlugField(max_length=20, primary_key=True) + field2 = SlugField(max_length=20) + + class Meta: + app_label = "schema" + + with connection.schema_editor() as editor: + editor.create_model(SimpleModel) + self.assertEqual( + self.get_constraints_for_column(SimpleModel, "field1"), + [ + "schema_simplemodel_field1_f07a3d6a_like", + "schema_simplemodel_pkey", + ], + ) + # Remove primary_key from field1. + old_field1 = SimpleModel._meta.get_field("field1") + new_field1 = CharField(max_length=20, primary_key=False) + new_field1.set_attributes_from_name("field1") + with connection.schema_editor() as editor: + editor.alter_field(SimpleModel, old_field1, new_field1, strict=True) + self.assertEqual(self.get_constraints_for_column(SimpleModel, "field1"), []) + # Add primary_key to field2. + old_field2 = SimpleModel._meta.get_field("field2") + new_field2 = CharField(max_length=20, primary_key=True) + new_field2.set_attributes_from_name("field2") + new_field2.model = SimpleModel + with connection.schema_editor() as editor: + editor.alter_field(SimpleModel, old_field2, new_field2, strict=True) + self.assertEqual( + self.get_constraints_for_column(SimpleModel, "field2"), + [ + "schema_simplemodel_field2_08772539_like", + "schema_simplemodel_field2_08772539_pk", + ], + ) + def test_alter_field_add_index_to_integerfield(self): # Create the table and verify no initial indexes. with connection.schema_editor() as editor: |
