From b0d76f9030ffa798880a3b595d3a9eaa473b34ef Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Mon, 30 Sep 2024 12:22:34 +0200 Subject: [PATCH] Add migrations for fixing unique constraints --- .../0018_fix_unique_constraints_1.py | 98 +++++++++++++++++++ .../0019_fix_unique_constraints_2.py | 53 ++++++++++ aleksis/apps/alsijil/models.py | 8 +- 3 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 aleksis/apps/alsijil/migrations/0018_fix_unique_constraints_1.py create mode 100644 aleksis/apps/alsijil/migrations/0019_fix_unique_constraints_2.py diff --git a/aleksis/apps/alsijil/migrations/0018_fix_unique_constraints_1.py b/aleksis/apps/alsijil/migrations/0018_fix_unique_constraints_1.py new file mode 100644 index 000000000..030379f36 --- /dev/null +++ b/aleksis/apps/alsijil/migrations/0018_fix_unique_constraints_1.py @@ -0,0 +1,98 @@ +# Generated by Django 4.2.16 on 2024-09-26 14:54 + +from django.db import migrations, models +from reversion.models import Version +from reversion import create_revision + +def fix_constraints(apps, schema_editor): + LessonDocumentation = apps.get_model("alsijil", "LessonDocumentation") + PersonalNote = apps.get_model("alsijil", "PersonalNote") + + with create_revision(): + personal_notes = PersonalNote.objects.filter(extra_lesson_id__isnull=False).values("extra_lesson_id", "person_id", "week", "year").annotate(count=models.Count("id")).filter(count__gt=1) + + + for personal_note in personal_notes: + affected_entries = PersonalNote.objects.filter(extra_lesson_id=personal_note["extra_lesson_id"], person_id=personal_note["person_id"]) + current_date = None + newest = None + for affected_entry in affected_entries: + versions = Version.objects.get_for_object(affected_entry) + if not versions: + if not newest: + newest = affected_entry + continue + version = versions[0] + if not current_date or version.revision.date_created > current_date: + current_date = version.revision.date_created + newest = affected_entry + + affected_entries.exclude(pk=newest.pk).delete() + + personal_notes = PersonalNote.objects.filter(event_id__isnull=False).values("event_id", "person_id", "week", "year").annotate(count=models.Count("id")).filter(count__gt=1) + + for personal_note in personal_notes: + affected_entries = PersonalNote.objects.filter(event_id=personal_note["event_id"], person_id=personal_note["person_id"]) + current_date = None + newest = None + for affected_entry in affected_entries: + versions = Version.objects.get_for_object(affected_entry) + if not versions: + if not newest: + newest = affected_entry + continue + version = versions[0] + if not current_date or version.revision.date_created > current_date: + current_date = version.revision.date_created + newest = affected_entry + + affected_entries.exclude(pk=newest.pk).delete() + + lesson_documentations = LessonDocumentation.objects.filter(extra_lesson_id__isnull=False).values("extra_lesson_id", "week", "year").annotate(count=models.Count("id")).filter(count__gt=1) + + for lesson_documentation in lesson_documentations: + affected_entries = LessonDocumentation.objects.filter(extra_lesson_id=lesson_documentation["extra_lesson_id"]) + current_date = None + newest = None + for affected_entry in affected_entries: + versions = Version.objects.get_for_object(affected_entry) + if not versions: + if not newest: + newest = affected_entry + continue + version = versions[0] + if not current_date or version.revision.date_created > current_date: + current_date = version.revision.date_created + newest = affected_entry + + affected_entries.exclude(pk=newest.pk).delete() + + + lesson_documentations = LessonDocumentation.objects.filter(event_id__isnull=False).values("event_id", "week", "year").annotate(count=models.Count("id")).filter(count__gt=1) + + for lesson_documentation in lesson_documentations: + affected_entries = LessonDocumentation.objects.filter(event_id=lesson_documentation["event_id"]) + current_date = None + newest = None + for affected_entry in affected_entries: + versions = Version.objects.get_for_object(affected_entry) + if not versions: + if not newest: + newest = affected_entry + continue + version = versions[0] + if not current_date or version.revision.date_created > current_date: + current_date = version.revision.date_created + newest = affected_entry + + affected_entries.exclude(pk=newest.pk).delete() + +class Migration(migrations.Migration): + + dependencies = [ + ("alsijil", "0017_rename_late_to_tardiness"), + ] + + operations = [ + migrations.RunPython(fix_constraints), + ] diff --git a/aleksis/apps/alsijil/migrations/0019_fix_unique_constraints_2.py b/aleksis/apps/alsijil/migrations/0019_fix_unique_constraints_2.py new file mode 100644 index 000000000..e20d5e139 --- /dev/null +++ b/aleksis/apps/alsijil/migrations/0019_fix_unique_constraints_2.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.16 on 2024-09-26 14:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("alsijil", "0018_fix_unique_constraints_1"), + ] + + operations = [ + migrations.RemoveConstraint( + model_name="lessondocumentation", + name="unique_documentation_per_ev", + ), + migrations.RemoveConstraint( + model_name="lessondocumentation", + name="unique_documentation_per_el", + ), + migrations.RemoveConstraint( + model_name="personalnote", + name="unique_note_per_ev", + ), + migrations.RemoveConstraint( + model_name="personalnote", + name="unique_note_per_el", + ), + migrations.AddConstraint( + model_name="lessondocumentation", + constraint=models.UniqueConstraint( + fields=("event",), name="unique_documentation_per_ev" + ), + ), + migrations.AddConstraint( + model_name="lessondocumentation", + constraint=models.UniqueConstraint( + fields=("extra_lesson",), name="unique_documentation_per_el" + ), + ), + migrations.AddConstraint( + model_name="personalnote", + constraint=models.UniqueConstraint( + fields=("event", "person"), name="unique_note_per_ev" + ), + ), + migrations.AddConstraint( + model_name="personalnote", + constraint=models.UniqueConstraint( + fields=("extra_lesson", "person"), name="unique_note_per_el" + ), + ), + ] diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index c9a964714..1950330ca 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -310,11 +310,11 @@ class PersonalNote(RegisterObjectRelatedMixin, ExtensibleModel): name="unique_note_per_lp", ), models.UniqueConstraint( - fields=("week", "year", "event", "person"), + fields=("event", "person"), name="unique_note_per_ev", ), models.UniqueConstraint( - fields=("week", "year", "extra_lesson", "person"), + fields=("extra_lesson", "person"), name="unique_note_per_el", ), ] @@ -413,11 +413,11 @@ class LessonDocumentation(RegisterObjectRelatedMixin, ExtensibleModel): name="unique_documentation_per_lp", ), models.UniqueConstraint( - fields=("week", "year", "event"), + fields=("event",), name="unique_documentation_per_ev", ), models.UniqueConstraint( - fields=("week", "year", "extra_lesson"), + fields=("extra_lesson",), name="unique_documentation_per_el", ), ] -- GitLab