from django.db import migrations # no additional imports required def normalize_and_dedupe(apps, schema_editor): Supervisor = apps.get_model('generic', 'Supervisor') UserProfile = apps.get_model('generic', 'UserProfile') CidUser = apps.get_model('generic', 'CidUser') # Build groups by normalized email without saving changes yet to avoid unique constraint errors supervisors = list(Supervisor.objects.all()) groups = {} for s in supervisors: norm_email = (s.email or "").strip().lower() norm_name = (s.name or "").strip() groups.setdefault(norm_email, []).append((s, norm_name)) # For each group, pick a keeper (smallest PK), reassign FKs from duplicates to keeper, delete duplicates, # then update the keeper's normalized email/name. for norm_email, entries in groups.items(): # pick keeper by lowest id entries_sorted = sorted(entries, key=lambda e: e[0].pk) keeper_obj, keeper_name = entries_sorted[0] # reassign duplicates for dup_obj, dup_name in entries_sorted[1:]: UserProfile.objects.filter(supervisor_id=dup_obj.pk).update(supervisor_id=keeper_obj.pk) CidUser.objects.filter(supervisor_id=dup_obj.pk).update(supervisor_id=keeper_obj.pk) dup_obj.delete() # update keeper's email and name to normalized values if needed changed = False if norm_email and keeper_obj.email != norm_email: keeper_obj.email = norm_email changed = True if keeper_name and keeper_obj.name != keeper_name: keeper_obj.name = keeper_name changed = True if changed: keeper_obj.save() class Migration(migrations.Migration): dependencies = [ ('generic', '0027_alter_questionreview_status'), ] operations = [ migrations.RunPython(normalize_and_dedupe, reverse_code=migrations.RunPython.noop), ]