Skip to content

Commit b8d86e7

Browse files
Batch-refresh close_old_findings status fields to avoid N refresh_from_db queries.
Replace per-finding refresh_from_db(false_p, risk_accepted, out_of_scope) with one values() query for all PKs and assign onto instances, falling back to refresh_from_db when a row is missing.
1 parent 876ff9c commit b8d86e7

1 file changed

Lines changed: 40 additions & 8 deletions

File tree

dojo/importers/default_reimporter.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,38 @@ def process_findings(
464464

465465
return self.new_items, self.reactivated_items, self.to_mitigate, self.untouched
466466

467+
def _sync_close_old_finding_status_fields(self, findings: list[Finding]) -> None:
468+
"""
469+
Refresh false_p, risk_accepted, and out_of_scope from the DB for each finding.
470+
471+
These can change during reimport (e.g. false positive) while the in-memory instances
472+
are stale. A naive refresh_from_db per finding issues one SELECT each; we batch one
473+
query for all primary keys and fall back to refresh_from_db only when needed.
474+
"""
475+
ids = [f.pk for f in findings if f.pk is not None]
476+
if not ids:
477+
for finding in findings:
478+
finding.refresh_from_db(fields=["false_p", "risk_accepted", "out_of_scope"])
479+
return
480+
481+
fresh_by_id = {
482+
row["id"]: row
483+
for row in Finding.objects.filter(pk__in=ids).values(
484+
"id",
485+
"false_p",
486+
"risk_accepted",
487+
"out_of_scope",
488+
)
489+
}
490+
for finding in findings:
491+
row = fresh_by_id.get(finding.pk)
492+
if row is not None:
493+
finding.false_p = row["false_p"]
494+
finding.risk_accepted = row["risk_accepted"]
495+
finding.out_of_scope = row["out_of_scope"]
496+
else:
497+
finding.refresh_from_db(fields=["false_p", "risk_accepted", "out_of_scope"])
498+
467499
def close_old_findings(
468500
self,
469501
findings: list[Finding],
@@ -477,17 +509,17 @@ def close_old_findings(
477509
if self.close_old_findings_toggle is False:
478510
return []
479511
logger.debug("REIMPORT_SCAN: Closing findings no longer present in scan report")
512+
# Get any status changes that could have occurred earlier in the process
513+
# for special statuses only.
514+
# An example of such is a finding being reported as false positive, and
515+
# reimport makes this change in the database. However, the findings here
516+
# are calculated based from the original values before the reimport, so
517+
# any updates made during reimport are discarded without first getting the
518+
# state of the finding as it stands at this moment
519+
self._sync_close_old_finding_status_fields(findings)
480520
# Determine if pushing to jira or if the finding groups are enabled
481521
mitigated_findings = []
482522
for finding in findings:
483-
# Get any status changes that could have occurred earlier in the process
484-
# for special statuses only.
485-
# An example of such is a finding being reported as false positive, and
486-
# reimport makes this change in the database. However, the findings here
487-
# are calculated based from the original values before the reimport, so
488-
# any updates made during reimport are discarded without first getting the
489-
# state of the finding as it stands at this moment
490-
finding.refresh_from_db(fields=["false_p", "risk_accepted", "out_of_scope"])
491523
# Ensure the finding is not already closed
492524
if not finding.mitigated or not finding.is_mitigated:
493525
logger.debug("mitigating finding: %i:%s", finding.id, finding)

0 commit comments

Comments
 (0)