blob: 5fa6a6f3ada6e963bf91c5444c48f60d79fe1221 [file] [log] [blame]
# -*- coding: utf-8 -*-
"""Migrations to set the unique constraints and drop duplicates."""
# pylint: disable=invalid-name
import logging
from django.db import migrations, models, connection
from django.db.models import Count, Min
from crashreports.models import HeartBeat, Crashreport
LOGGER = logging.getLogger(__name__)
def drop_heartbeat_duplicates(apps, schema_editor):
"""Drop duplicate heartbeat entries."""
# pylint: disable=unused-argument
find_and_drop_duplicates(HeartBeat)
def drop_crashreport_duplicates(apps, schema_editor):
"""Drop duplicate crashreport entries."""
# pylint: disable=unused-argument
find_and_drop_duplicates(Crashreport)
def find_and_drop_duplicates(object_type):
"""Drop all duplicates of the given object type."""
unique_fields = ("device", "date")
duplicates = (
object_type.objects.values(*unique_fields)
.order_by()
.annotate(min_id=Min("id"), num_duplicates=Count("id"))
.filter(num_duplicates__gt=1)
)
LOGGER.info(
"Found %d %s instances that have duplicates. These will be removed.",
duplicates.count(),
object_type.__name__,
)
for duplicate in duplicates:
LOGGER.debug("Removing duplicates: %s", duplicate)
(
object_type.objects.filter(
device=duplicate["device"], date=duplicate["date"]
)
.exclude(id=duplicate["min_id"])
.delete()
)
# Manually commit the data migration before schema migrations are applied
connection.cursor().execute("COMMIT;")
class Migration(migrations.Migration):
"""Change heartbeat date field, set unique constraints, drop duplicates."""
dependencies = [("crashreports", "0005_add_fp_staff_group")]
operations = [
migrations.AlterField(
model_name="heartbeat",
name="date",
field=models.DateField(db_index=True),
),
migrations.RunPython(
drop_heartbeat_duplicates, reverse_code=migrations.RunPython.noop
),
migrations.RunPython(
drop_crashreport_duplicates, reverse_code=migrations.RunPython.noop
),
migrations.AlterUniqueTogether(
name="crashreport", unique_together=set([("device", "date")])
),
migrations.AlterUniqueTogether(
name="heartbeat", unique_together=set([("device", "date")])
),
]