diff --git a/openedx/core/djangoapps/demographics/migrations/0002_clean_duplicate_entries.py b/openedx/core/djangoapps/demographics/migrations/0002_clean_duplicate_entries.py new file mode 100644 index 0000000000000000000000000000000000000000..bfadadf061b36df6e89712e5ecac3f8cfec7fbc6 --- /dev/null +++ b/openedx/core/djangoapps/demographics/migrations/0002_clean_duplicate_entries.py @@ -0,0 +1,48 @@ +import logging + +from django.conf import settings +from django.db import migrations, models + +log = logging.getLogger(__name__) + + +def _clean_duplicate_entries(apps, schema_editor): + """ + This method finds all the duplicate user entries in the UserDemographics model + and then removes all duplicate entries except for the most recently modified one. + """ + demographics_model = apps.get_model('demographics', 'UserDemographics') + # Retrieve a list of all users that have more than one entry. + duplicate_users = ( + demographics_model.objects.values( + 'user' + ).annotate(models.Count('id')).values('user').order_by().filter(id__count__gt=1) + ) + # Get a QuerySet of all the UserDemographics instances for the duplicates + # sorted by user and modified in descending order. + user_demographic_dupes = demographics_model.objects.filter(user__in=duplicate_users).order_by('user', '-modified') + + # Go through the QuerySet and only keep the most recent instance. + existing_user_ids = set() + for demographic in user_demographic_dupes: + if demographic.user_id in existing_user_ids: + log.info('UserDemographics {user} -- {modified}'.format( + user=demographic.user_id, modified=demographic.modified + )) + demographic.delete() + else: + log.info('UserDemographics Duplicate User Delete {user} -- {modified}'.format( + user=demographic.user_id, modified=demographic.modified + )) + existing_user_ids.add(demographic.user_id) + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('demographics', '0001_initial'), + ] + + operations = [ + migrations.RunPython(_clean_duplicate_entries, migrations.RunPython.noop), + ] diff --git a/openedx/core/djangoapps/demographics/migrations/0003_auto_20200827_1949.py b/openedx/core/djangoapps/demographics/migrations/0003_auto_20200827_1949.py new file mode 100644 index 0000000000000000000000000000000000000000..d31c24841ea60ba8312b4819ef9938db94361abd --- /dev/null +++ b/openedx/core/djangoapps/demographics/migrations/0003_auto_20200827_1949.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.15 on 2020-08-27 19:49 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('demographics', '0002_clean_duplicate_entries'), + ] + + operations = [ + migrations.AlterField( + model_name='userdemographics', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/openedx/core/djangoapps/demographics/models.py b/openedx/core/djangoapps/demographics/models.py index be8251c80c6a93d80b39338f17300c8e23c47f96..f576b77a632c1b76f3b92929e2be7fe82bdcec6e 100644 --- a/openedx/core/djangoapps/demographics/models.py +++ b/openedx/core/djangoapps/demographics/models.py @@ -11,7 +11,7 @@ class UserDemographics(TimeStampedModel): A Users Demographics platform related data in support of the Demographics IDA and features """ - user = models.ForeignKey(User, on_delete=models.CASCADE) + user = models.OneToOneField(User, on_delete=models.CASCADE) show_call_to_action = models.BooleanField(default=True) history = HistoricalRecords(app='demographics')