@@ -109,6 +109,30 @@ def _alter_field(
109109 strict = False ,
110110 ):
111111 collection = self .connection .database [model ._meta .db_table ]
112+ # Has unique been removed?
113+ if old_field .unique and (
114+ not new_field .unique or self ._field_became_primary_key (old_field , new_field )
115+ ):
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 )
112136 # Removed an index? (no strict check, as multiple indexes are possible)
113137 # Remove indexes if db_index switched to False or a unique constraint
114138 # will now be used in lieu of an index. The following lines from the
@@ -134,12 +158,29 @@ def _alter_field(
134158 ):
135159 self ._drop_index_for_field (model , old_field )
136160 self ._add_index_for_field (model , new_field )
161+ # Move unique to the new field, if needed.
162+ if old_field .unique and new_field .unique and new_field .column != "_id" :
163+ 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 )
137172 # Replace NULL with the field default if the field and was changed from
138173 # NULL to NOT NULL.
139174 if new_field .has_default () and old_field .null and not new_field .null :
140175 column = new_field .column
141176 default = self .effective_default (new_field )
142177 collection .update_many ({column : {"$eq" : None }}, [{"$set" : {column : default }}])
178+ # Added a unique?
179+ 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 )
143184 # Added an index? Add an index if db_index switched to True or a unique
144185 # constraint will no longer be used in lieu of an index. The following
145186 # lines from the truth table show all True cases; the rest are False:
0 commit comments