backend/code_review_backend/issues/migrations/0007_issuelink_swap.py (49 lines of code) (raw):

# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Generated by Django 4.1.2 on 2022-12-07 16:59 from math import ceil from django.db import migrations ISSUES_INSERT_SIZE = 1000 def generate_issue_links(apps, schema_editor): """Generate the IssueLink M2M table from issues' FK to the diff of a revision. Issues are migrated from the most recent to the oldest. The generation is done in small transactions, so the tables ar not locked for a long period of time (allowing to ingest new issues) and can be resumed later on. """ Issue = apps.get_model("issues", "Issue") IssueLink = apps.get_model("issues", "IssueLink") # Search for the IssueLink referencing the older issue older_issue_link = IssueLink.objects.order_by("issue__created").first() issue_filters = {} if older_issue_link is not None: issue_filters = {"created__lt": older_issue_link.issue.created} qs = ( # This ensures we do not handle newly created issues # during the migration so the order is preserved Issue.objects.filter(diff__isnull=False) .filter(**issue_filters) .order_by("-created", "id") .values("id", "diff_id", "diff__revision_id") ) issues_count = qs.count() slices = ceil(issues_count / ISSUES_INSERT_SIZE) for index in range(0, slices): current = min((index + 1) * ISSUES_INSERT_SIZE, issues_count) print( f"[{current}/{issues_count}] Initializing Issues references on the M2M table." ) issues = qs[index * ISSUES_INSERT_SIZE : (index + 1) * ISSUES_INSERT_SIZE] IssueLink.objects.bulk_create( IssueLink( issue_id=issue["id"], diff_id=issue["diff_id"], revision_id=issue["diff__revision_id"], ) for issue in issues ) class Migration(migrations.Migration): atomic = False dependencies = [ ("issues", "0006_issuelink_initial"), ] operations = [ # Fill the M2M table migrations.RunPython( generate_issue_links, reverse_code=None, elidable=True, atomic=False, ), # Drop old FK migrations.RemoveField( model_name="issue", name="diff", ), ]