@@ -66,15 +66,31 @@ def _alter_field(
66
66
strict = False ,
67
67
):
68
68
collection = self .connection .database [model ._meta .db_table ]
69
+ # Removed an index?
70
+ if self ._field_should_be_indexed (model , old_field ) and not self ._field_should_be_indexed (
71
+ model , new_field
72
+ ):
73
+ self ._remove_field_index (model , old_field )
69
74
# Have they renamed the column?
70
75
if old_field .column != new_field .column :
71
76
collection .update_many ({}, {"$rename" : {old_field .column : new_field .column }})
77
+ # Move index to the new field, if needed.
78
+ if self ._field_should_be_indexed (model , old_field ) and self ._field_should_be_indexed (
79
+ model , new_field
80
+ ):
81
+ self ._remove_field_index (model , old_field )
82
+ self ._add_field_index (model , new_field )
72
83
# Replace NULL with the field default if the field and was changed from
73
84
# NULL to NOT NULL.
74
85
if new_field .has_default () and old_field .null and not new_field .null :
75
86
column = new_field .column
76
87
default = self .effective_default (new_field )
77
88
collection .update_many ({column : {"$eq" : None }}, [{"$set" : {column : default }}])
89
+ # Added an index?
90
+ if not self ._field_should_be_indexed (model , old_field ) and self ._field_should_be_indexed (
91
+ model , new_field
92
+ ):
93
+ self ._add_field_index (model , new_field )
78
94
79
95
def remove_field (self , model , field ):
80
96
# Remove implicit M2M tables.
@@ -156,6 +172,28 @@ def _remove_composed_index(self, model, field_names, constraint_kwargs):
156
172
collection = self .connection .database [model ._meta .db_table ]
157
173
collection .drop_index (constraint_names [0 ])
158
174
175
+ def _remove_field_index (self , model , field ):
176
+ """Remove a field's db_index=True index."""
177
+ collection = self .connection .database [model ._meta .db_table ]
178
+ # Find the index for this field
179
+ meta_index_names = {index .name for index in model ._meta .indexes }
180
+ # Retrieve only BTREE indexes since this is what's created with
181
+ # db_index=True.
182
+ index_names = self ._constraint_names (
183
+ model ,
184
+ [field .column ],
185
+ index = True ,
186
+ type_ = Index .suffix ,
187
+ exclude = meta_index_names ,
188
+ )
189
+ if not index_names :
190
+ raise ValueError (f"Index not found for { model ._meta .db_table } .{ field .column } ." )
191
+ for index_name in index_names :
192
+ # The only way to check if an index was created with
193
+ # db_index=True or with Index(['field'], name='foo')
194
+ # is to look at its name (refs #28053).
195
+ collection .drop_index (index_name )
196
+
159
197
def add_constraint (self , model , constraint ):
160
198
pass
161
199
0 commit comments