@@ -68,11 +68,59 @@ def _alter_field(
68
68
new_db_params ,
69
69
strict = False ,
70
70
):
71
+ # Removed an index? (no strict check, as multiple indexes are possible)
72
+ # Remove indexes if db_index switched to False or a unique constraint
73
+ # will now be used in lieu of an index. The following lines from the
74
+ # truth table show all True cases; the rest are False:
75
+ #
76
+ # old_field.db_index | old_field.unique | new_field.db_index | new_field.unique
77
+ # ------------------------------------------------------------------------------
78
+ # True | False | False | False
79
+ # True | False | False | True
80
+ # True | False | True | True
81
+ if (
82
+ old_field .db_index
83
+ and not old_field .unique
84
+ and (not new_field .db_index or new_field .unique )
85
+ ):
86
+ # Find the index for this field
87
+ meta_index_names = {index .name for index in model ._meta .indexes }
88
+ # Retrieve only BTREE indexes since this is what's created with
89
+ # db_index=True.
90
+ index_names = self ._constraint_names (
91
+ model ,
92
+ [old_field .column ],
93
+ index = True ,
94
+ type_ = Index .suffix ,
95
+ exclude = meta_index_names ,
96
+ )
97
+ for index_name in index_names :
98
+ # The only way to check if an index was created with
99
+ # db_index=True or with Index(['field'], name='foo')
100
+ # is to look at its name (refs #28053).
101
+ self .connection .database [model ._meta .db_table ].drop_index (index_name )
71
102
# Have they renamed the column?
72
103
if old_field .column != new_field .column :
73
104
self .connection .database [model ._meta .db_table ].update_many (
74
105
{}, {"$rename" : {old_field .column : new_field .column }}
75
106
)
107
+ # Added an index? Add an index if db_index switched to True or a unique
108
+ # constraint will no longer be used in lieu of an index. The following
109
+ # lines from the truth table show all True cases; the rest are False:
110
+ #
111
+ # old_field.db_index | old_field.unique | new_field.db_index | new_field.unique
112
+ # ------------------------------------------------------------------------------
113
+ # False | False | True | False
114
+ # False | True | True | False
115
+ # True | True | True | False
116
+ if (
117
+ (not old_field .db_index or old_field .unique )
118
+ and new_field .db_index
119
+ and not new_field .unique
120
+ ):
121
+ index = Index (fields = [new_field .name ])
122
+ index .name = self ._create_index_name (model ._meta .db_table , [new_field .column ])
123
+ self .add_index (model , index )
76
124
77
125
def remove_field (self , model , field ):
78
126
# Remove implicit M2M tables.
0 commit comments