in backend/code_review_backend/issues/management/commands/cleanup_issues.py [0:0]
def handle(self, *args, **options):
self.cleanup_repositories()
clean_until = timezone.now() - timedelta(days=options["nb_days"])
rev_to_delete = Revision.objects.filter(
created__lte=clean_until,
)
total_rev_count = rev_to_delete.count()
if not total_rev_count:
logger.info("Didn't find any old revision to delete.")
return
logger.info(f"Retrieved {total_rev_count} old revisions to be deleted.")
stats = defaultdict(int)
iterations = math.ceil(total_rev_count / DEL_CHUNK_SIZE)
for i, start in enumerate(range(0, total_rev_count, DEL_CHUNK_SIZE), start=1):
logger.info(f"Page {i}/{iterations}.")
# First fetch revisions IDs in a first DB request
chunk_rev_ids = rev_to_delete.order_by("id")[
start : start + DEL_CHUNK_SIZE
].values_list("id", flat=True)
# Store IDs of related Issues, to make issues deletion faster later on
chunk_issues_ids = list(
Issue.objects.filter(
issue_links__revision_id__in=chunk_rev_ids
).values_list("id", flat=True)
)
# Delete IssueLink for this chunk
links_qs = IssueLink.objects.filter(revision_id__in=chunk_rev_ids)
links_count = links_qs._raw_delete(links_qs.db)
stats["IssueLink"] += links_count
# Perform a raw deletion to avoid Django performing lookups to IssueLink
# as the M2M has already be cleaned up at this stage.
diffs_qs = Diff.objects.filter(revision__id__in=chunk_rev_ids)
diffs_count = diffs_qs._raw_delete(diffs_qs.db)
stats["Diff"] += diffs_count
# Only delete issues that are not linked to a revision anymore
issues_qs = Issue.objects.filter(
id__in=chunk_issues_ids,
issue_links=None,
)
# Perform a raw deletion to avoid Django performing lookups to IssueLink
# as the M2M has already be cleaned up at this stage.
issues_count = issues_qs._raw_delete(issues_qs.db)
stats["Issue"] += issues_count
# Drop the revisions with a raw deletion to avoid Django performing lookups to IssueLink
# as the M2M has already be cleaned up at this stage.
rev_count = rev_to_delete._raw_delete(rev_to_delete.db)
stats["Revision"] += rev_count
msg = ", ".join((f"{n} {key}" for key, n in stats.items()))
logger.info(f"Deleted {msg}.")