@@ -82,6 +82,8 @@ def fetch_for_packages(
8282 return results
8383
8484 vulnerablecode = VulnerableCode (dataspace )
85+ # Tracks advisory_uids created during this run to avoid re-updating them in later batches.
86+ created_advisory_uids = set ()
8587
8688 for index , batch in enumerate (chunked_queryset (queryset , batch_size ), start = 1 ):
8789 batch_start = timer ()
@@ -122,6 +124,7 @@ def fetch_for_packages(
122124 update ,
123125 batch_results ,
124126 vulnerability_cache ,
127+ created_advisory_uids ,
125128 log_func ,
126129 verbosity ,
127130 )
@@ -174,7 +177,15 @@ def batch_add_affected(affected_packages, vulnerabilities):
174177
175178
176179def process_vc_entry (
177- vc_entry , queryset , dataspace , update , results , vulnerability_cache , log_func = None , verbosity = 1
180+ vc_entry ,
181+ queryset ,
182+ dataspace ,
183+ update ,
184+ results ,
185+ vulnerability_cache ,
186+ created_advisory_uids ,
187+ log_func = None ,
188+ verbosity = 1 ,
178189):
179190 """
180191 Process a single VulnerableCode purl entry: find the matching packages in ``queryset``,
@@ -227,6 +238,7 @@ def process_vc_entry(
227238 update ,
228239 results ,
229240 vulnerability = vulnerability_cache .get (advisory_uid ),
241+ created_advisory_uids = created_advisory_uids ,
230242 )
231243 vulnerability_cache [advisory_uid ] = vulnerability
232244 vulnerabilities .append (vulnerability )
@@ -242,22 +254,29 @@ def process_vc_entry(
242254
243255
244256def create_or_update_vulnerability (
245- vulnerability_data , dataspace , update , results , vulnerability = None
257+ vulnerability_data , dataspace , update , results , vulnerability = None , created_advisory_uids = None
246258):
247259 """
248260 Create or update a Vulnerability from ``vulnerability_data``.
249261
250262 ``vulnerability`` is the already-resolved instance (looked up from the caller's
251263 ``vulnerability_cache``), or ``None`` if not yet created. M2M linking is handled
252264 by the caller via ``batch_add_affected``.
265+
266+ ``created_advisory_uids`` is a run-wide set of advisory_uids created during this fetch.
267+ Vulnerabilities in this set are skipped for updates to avoid spurious re-updates when the
268+ same advisory appears in multiple packages across different batches.
253269 """
270+ advisory_uid = vulnerability_data ["advisory_uid" ]
254271 if not vulnerability :
255272 vulnerability = Vulnerability .create_from_data (
256273 dataspace = dataspace ,
257274 data = vulnerability_data ,
258275 )
259276 results ["created" ] += 1
260- elif update :
277+ if created_advisory_uids is not None :
278+ created_advisory_uids .add (advisory_uid )
279+ elif update and advisory_uid not in (created_advisory_uids or ()):
261280 updated_fields = vulnerability .update_from_data (
262281 user = None ,
263282 data = vulnerability_data ,
0 commit comments