@@ -26,10 +26,7 @@ def _create_model_indexes(self, model):
26
26
# Field uniques
27
27
for field in model ._meta .local_fields :
28
28
if field .unique and field .column != "_id" :
29
- constraint = UniqueConstraint (
30
- fields = [field .name ], name = f"{ model ._meta .db_table } _{ field .column } _key"
31
- )
32
- self .add_constraint (model , constraint )
29
+ self ._add_unique_for_field (model , field )
33
30
# Meta.index_together (RemovedInDjango51Warning)
34
31
for field_names in model ._meta .index_together :
35
32
index = Index (fields = field_names )
@@ -66,10 +63,7 @@ def add_field(self, model, field):
66
63
if self ._field_should_be_indexed (model , field ):
67
64
self ._add_index_for_field (model , field )
68
65
if field .unique and field .column != "_id" :
69
- constraint = UniqueConstraint (
70
- fields = [field .name ], name = f"{ model ._meta .db_table } _{ field .column } _key"
71
- )
72
- self .add_constraint (model , constraint , field = field )
66
+ self ._add_unique_for_field (model , field )
73
67
74
68
def _add_index_for_field (self , model , field ):
75
69
new_index = Index (fields = [field .name ])
@@ -97,6 +91,30 @@ def _drop_index_for_field(self, model, field):
97
91
# is to look at its name (refs #28053).
98
92
collection .drop_index (index_name )
99
93
94
+ def _add_unique_for_field (self , model , field ):
95
+ constraint = UniqueConstraint (
96
+ fields = [field .name ], name = f"{ model ._meta .db_table } _{ field .column } _key"
97
+ )
98
+ self .add_constraint (model , constraint , field = field )
99
+
100
+ def _drop_unique_for_field (self , model , field , strict ):
101
+ # Find the unique constraint for this field
102
+ meta_constraint_names = {constraint .name for constraint in model ._meta .constraints }
103
+ constraint_names = self ._constraint_names (
104
+ model ,
105
+ [field .column ],
106
+ unique = True ,
107
+ primary_key = False ,
108
+ exclude = meta_constraint_names ,
109
+ )
110
+ if strict and len (constraint_names ) != 1 :
111
+ raise ValueError (
112
+ f"Found wrong number ({ len (constraint_names )} ) of unique "
113
+ f"constraints for { model ._meta .db_table } .{ field .column } "
114
+ )
115
+ for constraint_name in constraint_names :
116
+ self .connection .database [model ._meta .db_table ].drop_index (constraint_name )
117
+
100
118
def _alter_field (
101
119
self ,
102
120
model ,
@@ -113,26 +131,7 @@ def _alter_field(
113
131
if old_field .unique and (
114
132
not new_field .unique or self ._field_became_primary_key (old_field , new_field )
115
133
):
116
- # Find the unique constraint for this field
117
- meta_constraint_names = {constraint .name for constraint in model ._meta .constraints }
118
- constraint_names = self ._constraint_names (
119
- model ,
120
- [old_field .column ],
121
- unique = True ,
122
- primary_key = False ,
123
- exclude = meta_constraint_names ,
124
- )
125
- if strict and len (constraint_names ) != 1 :
126
- raise ValueError (
127
- f"Found wrong number ({ len (constraint_names )} ) of unique "
128
- f"constraints for { model ._meta .db_table } .{ old_field .column } "
129
- )
130
- for constraint_name in constraint_names :
131
- constraint = UniqueConstraint (
132
- fields = [old_field .name ],
133
- name = constraint_name ,
134
- )
135
- self .remove_constraint (model , constraint )
134
+ self ._drop_unique_for_field (model , old_field , strict )
136
135
# Removed an index? (no strict check, as multiple indexes are possible)
137
136
# Remove indexes if db_index switched to False or a unique constraint
138
137
# will now be used in lieu of an index. The following lines from the
@@ -161,14 +160,8 @@ def _alter_field(
161
160
# Move unique to the new field, if needed.
162
161
if old_field .unique and new_field .unique and new_field .column != "_id" :
163
162
if not old_field .primary_key :
164
- old_constraint = UniqueConstraint (
165
- fields = [old_field .name ], name = f"{ model ._meta .db_table } _{ old_field .column } _key"
166
- )
167
- self .remove_constraint (model , old_constraint )
168
- new_constraint = UniqueConstraint (
169
- fields = [new_field .name ], name = f"{ model ._meta .db_table } _{ new_field .column } _key"
170
- )
171
- self .add_constraint (model , new_constraint , field = new_field )
163
+ self ._drop_unique_for_field (model , old_field , strict )
164
+ self ._add_unique_for_field (model , new_field )
172
165
# Replace NULL with the field default if the field and was changed from
173
166
# NULL to NOT NULL.
174
167
if new_field .has_default () and old_field .null and not new_field .null :
@@ -177,10 +170,7 @@ def _alter_field(
177
170
collection .update_many ({column : {"$eq" : None }}, [{"$set" : {column : default }}])
178
171
# Added a unique?
179
172
if self ._unique_should_be_added (old_field , new_field ):
180
- constraint = UniqueConstraint (
181
- fields = [new_field .name ], name = f"{ model ._meta .db_table } _{ new_field .column } _key"
182
- )
183
- self .add_constraint (model , constraint , field = new_field )
173
+ self ._add_unique_for_field (model , new_field )
184
174
# Added an index? Add an index if db_index switched to True or a unique
185
175
# constraint will no longer be used in lieu of an index. The following
186
176
# lines from the truth table show all True cases; the rest are False:
0 commit comments