mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #35180 -- Recreated PostgreSQL _like indexes when changing between TextField and CharField field types.
This commit is contained in:
		| @@ -140,6 +140,13 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|                     return sequence["name"] | ||||
|         return None | ||||
|  | ||||
|     def _is_changing_type_of_indexed_text_column(self, old_field, old_type, new_type): | ||||
|         return (old_field.db_index or old_field.unique) and ( | ||||
|             (old_type.startswith("varchar") and not new_type.startswith("varchar")) | ||||
|             or (old_type.startswith("text") and not new_type.startswith("text")) | ||||
|             or (old_type.startswith("citext") and not new_type.startswith("citext")) | ||||
|         ) | ||||
|  | ||||
|     def _alter_column_type_sql( | ||||
|         self, model, old_field, new_field, new_type, old_collation, new_collation | ||||
|     ): | ||||
| @@ -147,11 +154,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|         # different type. | ||||
|         old_db_params = old_field.db_parameters(connection=self.connection) | ||||
|         old_type = old_db_params["type"] | ||||
|         if (old_field.db_index or old_field.unique) and ( | ||||
|             (old_type.startswith("varchar") and not new_type.startswith("varchar")) | ||||
|             or (old_type.startswith("text") and not new_type.startswith("text")) | ||||
|             or (old_type.startswith("citext") and not new_type.startswith("citext")) | ||||
|         ): | ||||
|         if self._is_changing_type_of_indexed_text_column(old_field, old_type, new_type): | ||||
|             index_name = self._create_index_name( | ||||
|                 model._meta.db_table, [old_field.column], suffix="_like" | ||||
|             ) | ||||
| @@ -277,8 +280,14 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|             strict, | ||||
|         ) | ||||
|         # Added an index? Create any PostgreSQL-specific indexes. | ||||
|         if (not (old_field.db_index or old_field.unique) and new_field.db_index) or ( | ||||
|             not old_field.unique and new_field.unique | ||||
|         if ( | ||||
|             (not (old_field.db_index or old_field.unique) and new_field.db_index) | ||||
|             or (not old_field.unique and new_field.unique) | ||||
|             or ( | ||||
|                 self._is_changing_type_of_indexed_text_column( | ||||
|                     old_field, old_type, new_type | ||||
|                 ) | ||||
|             ) | ||||
|         ): | ||||
|             like_index_statement = self._create_like_index_sql(model, new_field) | ||||
|             if like_index_statement is not None: | ||||
|   | ||||
| @@ -5223,6 +5223,51 @@ class SchemaTests(TransactionTestCase): | ||||
|             ["schema_tag_slug_2c418ba3_like", "schema_tag_slug_key"], | ||||
|         ) | ||||
|  | ||||
|     @isolate_apps("schema") | ||||
|     @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||||
|     def test_indexed_charfield_to_textfield(self): | ||||
|         class SimpleModel(Model): | ||||
|             field1 = CharField(max_length=10, db_index=True) | ||||
|  | ||||
|             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", | ||||
|                 "schema_simplemodel_field1_f07a3d6a_like", | ||||
|             ], | ||||
|         ) | ||||
|         # Change to TextField. | ||||
|         old_field1 = SimpleModel._meta.get_field("field1") | ||||
|         new_field1 = TextField(db_index=True) | ||||
|         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"), | ||||
|             [ | ||||
|                 "schema_simplemodel_field1_f07a3d6a", | ||||
|                 "schema_simplemodel_field1_f07a3d6a_like", | ||||
|             ], | ||||
|         ) | ||||
|         # Change back to CharField. | ||||
|         old_field1 = SimpleModel._meta.get_field("field1") | ||||
|         new_field1 = CharField(max_length=10, db_index=True) | ||||
|         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"), | ||||
|             [ | ||||
|                 "schema_simplemodel_field1_f07a3d6a", | ||||
|                 "schema_simplemodel_field1_f07a3d6a_like", | ||||
|             ], | ||||
|         ) | ||||
|  | ||||
|     def test_alter_field_add_index_to_integerfield(self): | ||||
|         # Create the table and verify no initial indexes. | ||||
|         with connection.schema_editor() as editor: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user