Skip to content

Commit e569347

Browse files
authored
Merge pull request #14798 from valentijnscholten/fix/remove-obsolete-outside-scope-delete
async delete: remove obsolete outside scope delete
2 parents fc1c8e5 + 6d03180 commit e569347

1 file changed

Lines changed: 5 additions & 22 deletions

File tree

dojo/utils.py

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,35 +1783,18 @@ def async_delete_task(obj, **kwargs):
17831783

17841784
# Step 2: Prepare duplicate clusters (must happen before any deletion)
17851785
# When CASCADE_DELETE=True, reconfigure_duplicate_cluster skips reconfiguration —
1786-
# we handle that below by expanding scope to include outside duplicates.
1786+
# and deletes any outside scope duplicates to avoid FK violations during chunked deletion.
17871787
prepare_duplicates_for_delete(obj)
17881788

1789-
# Step 3: Delete outside-scope duplicates first — these point to findings
1790-
# in the main scope via duplicate_finding FK, so they must be removed before
1791-
# the originals to avoid FK violations during chunked deletion.
1792-
scope_ids = finding_qs.values_list("id", flat=True)
1793-
outside_dupes_qs = (
1794-
Finding.objects.filter(duplicate_finding_id__in=scope_ids)
1795-
.exclude(id__in=scope_ids)
1796-
)
1789+
# Step 3: Delete the main scope findings
17971790
chunk_size = get_setting("ASYNC_OBEJECT_DELETE_CHUNK_SIZE")
1798-
outside_count = outside_dupes_qs.count()
1799-
if outside_count:
1800-
logger.info("ASYNC_DELETE: Deleting %d outside-scope duplicates first", outside_count)
1801-
bulk_delete_findings(
1802-
outside_dupes_qs,
1803-
chunk_size=chunk_size,
1804-
cascade_root=cascade_root,
1805-
)
1806-
1807-
# Step 4: Delete the main scope findings
18081791
bulk_delete_findings(
18091792
finding_qs,
18101793
chunk_size=chunk_size,
18111794
cascade_root=cascade_root,
18121795
)
18131796

1814-
# Step 5: Delete all remaining related objects (Tests, Engagements,
1797+
# Step 4: Delete all remaining related objects (Tests, Engagements,
18151798
# Endpoints, etc.) via SQL cascade. Findings are already gone, so
18161799
# skip_relations={Finding} avoids walking empty relations.
18171800
# Single transaction is fine here — the heavy relations (Findings,
@@ -1820,12 +1803,12 @@ def async_delete_task(obj, **kwargs):
18201803
with transaction.atomic():
18211804
cascade_delete_related_objects(type(obj), pk_query, skip_relations={Finding})
18221805

1823-
# Step 6: Delete the top-level object via ORM to fire Django signals
1806+
# Step 5: Delete the top-level object via ORM to fire Django signals
18241807
# (post_delete notifications, pghistory audit, Pro signals).
18251808
# All children are already gone so this is a single-row DELETE.
18261809
obj.delete()
18271810

1828-
# Step 7: Recalculate product grade once (Engagement/Test deletes only). Skip when the
1811+
# Step 6: Recalculate product grade once (Engagement/Test deletes only). Skip when the
18291812
# deleted object is the Product itself — it is removed in step 6 and grading is pointless.
18301813
# For Product TYpe deletiongs we don't have a product instance, so this never fires.
18311814
if product and not isinstance(obj, Product):

0 commit comments

Comments
 (0)