summaryrefslogtreecommitdiff
path: root/tests/schema
diff options
context:
space:
mode:
authorBen Cail <bcail@crossway.org>2024-02-01 16:08:42 -0500
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-07-30 17:27:10 +0200
commit9cf9c796be8dd53bc3b11355ff39d65c81d7be6d (patch)
tree3d5e2c2a4bd8cdac02f079b2a62135e575f19687 /tests/schema
parent7e00fee3bd3b780667f072325bdb69f29144c553 (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.py14
-rw-r--r--tests/schema/tests.py211
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: