mirror of
				https://github.com/django/django.git
				synced 2025-10-28 08:06:09 +00:00 
			
		
		
		
	[1.8.x] Fixed #26034 -- Fixed incorrect index handling on PostgreSQL on Char/TextField with unique=True and db_index=True.
Thanks Simon Charette for review.
Backport of 56aaae58a7 from master
			
			
This commit is contained in:
		| @@ -107,13 +107,13 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): | ||||
|             new_db_params, strict, | ||||
|         ) | ||||
|         # Added an index? Create any PostgreSQL-specific indexes. | ||||
|         if ((not old_field.db_index and new_field.db_index) or (not old_field.unique and new_field.unique)): | ||||
|         if not old_field.db_index and not old_field.unique and (new_field.db_index or new_field.unique): | ||||
|             like_index_statement = self._create_like_index_sql(model, new_field) | ||||
|             if like_index_statement is not None: | ||||
|                 self.execute(like_index_statement) | ||||
|  | ||||
|         # Removed an index? Drop any PostgreSQL-specific indexes. | ||||
|         if ((not new_field.db_index and old_field.db_index) or (not new_field.unique and old_field.unique)): | ||||
|         if (old_field.db_index or old_field.unique) and not (new_field.db_index or new_field.unique): | ||||
|             index_to_remove = self._create_index_name(model, [old_field.column], suffix='_like') | ||||
|             index_names = self._constraint_names(model, [old_field.column], index=True) | ||||
|             for index_name in index_names: | ||||
|   | ||||
| @@ -18,3 +18,8 @@ Bugfixes | ||||
| * Fixed a regression that caused the incorrect day to be selected when opening | ||||
|   the admin calendar widget for timezones from GMT+0100 to GMT+1200 | ||||
|   (:ticket:`24980`). | ||||
|  | ||||
| * Fixed incorrect index handling in migrations on PostgreSQL when adding | ||||
|   ``db_index=True`` or ``unique=True`` to a ``CharField`` or ``TextField`` that | ||||
|   already had the other specified, or when removing one of them from a field | ||||
|   that had both (:ticket:`26034`). | ||||
|   | ||||
| @@ -1592,3 +1592,45 @@ class SchemaTests(TransactionTestCase): | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.alter_field(Note, new_field, old_field, strict=True) | ||||
|         self.assertEqual(self.get_constraints_for_column(Note, 'info'), []) | ||||
|  | ||||
|     @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific") | ||||
|     def test_alter_field_add_unique_to_charfield_with_db_index(self): | ||||
|         # Create the table and verify initial indexes. | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.create_model(BookWithoutAuthor) | ||||
|         self.assertEqual(len(self.get_constraints_for_column(BookWithoutAuthor, 'title')), 2) | ||||
|         # Alter to add unique=True (should add 1 index) | ||||
|         old_field = BookWithoutAuthor._meta.get_field('title') | ||||
|         new_field = CharField(max_length=100, db_index=True, unique=True) | ||||
|         new_field.set_attributes_from_name('title') | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.alter_field(BookWithoutAuthor, old_field, new_field, strict=True) | ||||
|         self.assertEqual(len(self.get_constraints_for_column(BookWithoutAuthor, 'title')), 3) | ||||
|         # Alter to remove unique=True (should drop unique index) # XXX: bug! | ||||
|         old_field = BookWithoutAuthor._meta.get_field('title') | ||||
|         new_field = CharField(max_length=100, db_index=True) | ||||
|         new_field.set_attributes_from_name('title') | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.alter_field(BookWithoutAuthor, old_field, new_field, strict=True) | ||||
|         self.assertEqual(len(self.get_constraints_for_column(BookWithoutAuthor, 'title')), 3) | ||||
|  | ||||
|     @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific") | ||||
|     def test_alter_field_add_db_index_to_charfield_with_unique(self): | ||||
|         # Create the table and verify initial indexes. | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.create_model(Tag) | ||||
|         self.assertEqual(len(self.get_constraints_for_column(Tag, 'slug')), 2) | ||||
|         # Alter to add db_index=True | ||||
|         old_field = Tag._meta.get_field('slug') | ||||
|         new_field = SlugField(db_index=True, unique=True) | ||||
|         new_field.set_attributes_from_name('slug') | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.alter_field(Tag, old_field, new_field, strict=True) | ||||
|         self.assertEqual(len(self.get_constraints_for_column(Tag, 'slug')), 2) | ||||
|         # Alter to remove db_index=True | ||||
|         old_field = Tag._meta.get_field('slug') | ||||
|         new_field = SlugField(unique=True) | ||||
|         new_field.set_attributes_from_name('slug') | ||||
|         with connection.schema_editor() as editor: | ||||
|             editor.alter_field(Tag, old_field, new_field, strict=True) | ||||
|         self.assertEqual(len(self.get_constraints_for_column(Tag, 'slug')), 2) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user