@@ -97,7 +97,6 @@ def add_field(self, model, field):
97
97
self ._create_model_indexes (
98
98
field .embedded_model , parent_model = model , column_prefix = new_path
99
99
)
100
-
101
100
# Add an index or unique, if required.
102
101
if self ._field_should_be_indexed (model , field ):
103
102
self ._add_field_index (model , field )
@@ -162,13 +161,65 @@ def remove_field(self, model, field):
162
161
self ._remove_field_index (model , field )
163
162
elif self ._field_should_have_unique (field ):
164
163
self ._remove_field_unique (model , field )
164
+ if isinstance (field , EmbeddedModelField ):
165
+ new_path = f"{ field .column } ."
166
+ self ._remove_model_indexes (
167
+ field .embedded_model , parent_model = model , column_prefix = new_path
168
+ )
169
+
170
+ def _remove_model_indexes (self , model , column_prefix = "" , parent_model = None ):
171
+ """
172
+ When removing an EmbeddedModelField, the indexes need to be removed
173
+ recursively.
174
+ """
175
+ if not model ._meta .managed or model ._meta .proxy or model ._meta .swapped :
176
+ return
177
+ # Field indexes and uniques
178
+ for field in model ._meta .local_fields :
179
+ if isinstance (field , EmbeddedModelField ):
180
+ new_path = f"{ column_prefix } { field .column } ."
181
+ self ._remove_model_indexes (
182
+ field .embedded_model , parent_model = parent_model or model , column_prefix = new_path
183
+ )
184
+ if self ._field_should_be_indexed (model , field ):
185
+ self ._remove_field_index (parent_model or model , field , column_prefix = column_prefix )
186
+ elif self ._field_should_have_unique (field ):
187
+ self ._remove_field_unique (parent_model or model , field , column_prefix = column_prefix )
188
+ # Meta.index_together (RemovedInDjango51Warning)
189
+ for field_names in model ._meta .index_together :
190
+ self ._remove_composed_index (
191
+ model ,
192
+ field_names ,
193
+ {"index" : True , "unique" : False },
194
+ column_prefix = column_prefix ,
195
+ parent_model = parent_model ,
196
+ )
197
+ # Meta.unique_together
198
+ if model ._meta .unique_together :
199
+ self .alter_unique_together (
200
+ model ,
201
+ model ._meta .unique_together ,
202
+ [],
203
+ column_prefix = column_prefix ,
204
+ parent_model = parent_model ,
205
+ )
206
+ # Meta.constraints
207
+ for constraint in model ._meta .constraints :
208
+ self .remove_constraint (
209
+ model , constraint , column_prefix = column_prefix , parent_model = parent_model
210
+ )
211
+ # Meta.indexes
212
+ for index in model ._meta .indexes :
213
+ self .remove_index (model , index , column_prefix = column_prefix , parent_model = parent_model )
165
214
166
215
def alter_index_together (self , model , old_index_together , new_index_together , column_prefix = "" ):
167
216
olds = {tuple (fields ) for fields in old_index_together }
168
217
news = {tuple (fields ) for fields in new_index_together }
169
218
# Deleted indexes
170
219
for field_names in olds .difference (news ):
171
- self ._remove_composed_index (model , field_names , {"index" : True , "unique" : False })
220
+ self ._remove_composed_index (
221
+ model , field_names , {"index" : True , "unique" : False }, column_prefix = ""
222
+ )
172
223
# Created indexes
173
224
for field_names in news .difference (olds ):
174
225
self ._add_composed_index (model , field_names , column_prefix = column_prefix )
@@ -256,16 +307,18 @@ def remove_index(self, model, index):
256
307
return
257
308
self .get_collection (model ._meta .db_table ).drop_index (index .name )
258
309
259
- def _remove_composed_index (self , model , field_names , constraint_kwargs ):
310
+ def _remove_composed_index (
311
+ self , model , field_names , constraint_kwargs , column_prefix = "" , parent_model = None
312
+ ):
260
313
"""
261
314
Remove the index on the given list of field_names created by
262
315
index/unique_together, depending on constraint_kwargs.
263
316
"""
264
317
meta_constraint_names = {constraint .name for constraint in model ._meta .constraints }
265
318
meta_index_names = {constraint .name for constraint in model ._meta .indexes }
266
- columns = [model ._meta .get_field (field ).column for field in field_names ]
319
+ columns = [column_prefix + model ._meta .get_field (field ).column for field in field_names ]
267
320
constraint_names = self ._constraint_names (
268
- model ,
321
+ parent_model or model ,
269
322
columns ,
270
323
exclude = meta_constraint_names | meta_index_names ,
271
324
** constraint_kwargs ,
@@ -277,16 +330,17 @@ def _remove_composed_index(self, model, field_names, constraint_kwargs):
277
330
f"Found wrong number ({ num_found } ) of constraints for "
278
331
f"{ model ._meta .db_table } ({ columns_str } )."
279
332
)
333
+ model = parent_model or model
280
334
collection = self .get_collection (model ._meta .db_table )
281
335
collection .drop_index (constraint_names [0 ])
282
336
283
- def _remove_field_index (self , model , field ):
337
+ def _remove_field_index (self , model , field , column_prefix = "" ):
284
338
"""Remove a field's db_index=True index."""
285
339
collection = self .get_collection (model ._meta .db_table )
286
340
meta_index_names = {index .name for index in model ._meta .indexes }
287
341
index_names = self ._constraint_names (
288
342
model ,
289
- [field .column ],
343
+ [column_prefix + field .column ],
290
344
index = True ,
291
345
# Retrieve only BTREE indexes since this is what's created with
292
346
# db_index=True.
@@ -345,12 +399,12 @@ def remove_constraint(self, model, constraint):
345
399
)
346
400
self .remove_index (model , idx )
347
401
348
- def _remove_field_unique (self , model , field ):
402
+ def _remove_field_unique (self , model , field , column_prefix = "" ):
349
403
# Find the unique constraint for this field
350
404
meta_constraint_names = {constraint .name for constraint in model ._meta .constraints }
351
405
constraint_names = self ._constraint_names (
352
406
model ,
353
- [field .column ],
407
+ [column_prefix + field .column ],
354
408
unique = True ,
355
409
primary_key = False ,
356
410
exclude = meta_constraint_names ,
0 commit comments