@@ -431,7 +431,7 @@ def _try_reuse_deadline_uuids(
431431 existing_deadline_uuids : list [str ],
432432 new_deadline_data : list [dict ],
433433 session : Session ,
434- ) -> dict [str , dict ] | None :
434+ ) -> tuple [ dict [str , dict ], dict [ str , str | None ] ] | None :
435435 """
436436 Try to reuse existing deadline UUIDs if the deadline definitions haven't changed.
437437
@@ -440,7 +440,11 @@ def _try_reuse_deadline_uuids(
440440 :param existing_deadline_uuids: List of UUID strings from existing serialized Dag
441441 :param new_deadline_data: List of new deadline alert data dicts from the Dag
442442 :param session: Database session
443- :return: UUID mapping dict if all match, None if any mismatch detected
443+ :return: Tuple of (uuid_mapping, name_updates) if all definitions match, None if any
444+ mismatch detected. ``uuid_mapping`` maps UUID string → new deadline data dict.
445+ ``name_updates`` maps UUID string → new name **only** for entries whose name
446+ changed relative to the existing DB row, so callers can issue targeted UPDATEs
447+ and reliably detect whether any DB write occurred.
444448 """
445449 # defensive check for old 3.1.x format
446450 if existing_deadline_uuids and not isinstance (existing_deadline_uuids [0 ], str ):
@@ -468,6 +472,7 @@ def _definitions_match(deadline_data: dict, existing: DeadlineAlertModel) -> boo
468472
469473 matched_uuids : set [UUID ] = set ()
470474 uuid_mapping : dict [str , dict ] = {}
475+ name_updates : dict [str , str | None ] = {}
471476
472477 for deadline_alert in new_deadline_data :
473478 deadline_data = deadline_alert .get (Encoding .VAR , deadline_alert )
@@ -479,9 +484,13 @@ def _definitions_match(deadline_data: dict, existing: DeadlineAlertModel) -> boo
479484
480485 if _definitions_match (deadline_data , existing_alert ):
481486 # Found a match, reuse this UUID
482- uuid_mapping [str (existing_alert .id )] = deadline_data
487+ uuid_str = str (existing_alert .id )
488+ uuid_mapping [uuid_str ] = deadline_data
483489 matched_uuids .add (existing_alert .id )
484490 found_match = True
491+ new_name = deadline_data .get (DeadlineAlertFields .NAME )
492+ if new_name != existing_alert .name :
493+ name_updates [uuid_str ] = new_name
485494 break
486495
487496 if not found_match :
@@ -490,7 +499,7 @@ def _definitions_match(deadline_data: dict, existing: DeadlineAlertModel) -> boo
490499 # to another deadline), so partial reuse would risk stale cross-references.
491500 return None
492501
493- return uuid_mapping
502+ return uuid_mapping , name_updates
494503
495504 @classmethod
496505 def _create_deadline_alert_records (
@@ -510,6 +519,7 @@ def _create_deadline_alert_records(
510519 for uuid_str , deadline_data in uuid_mapping .items ():
511520 alert = DeadlineAlertModel (
512521 id = UUID (uuid_str ),
522+ name = deadline_data .get (DeadlineAlertFields .NAME ),
513523 reference = deadline_data [DeadlineAlertFields .REFERENCE ],
514524 interval = deadline_data [DeadlineAlertFields .INTERVAL ],
515525 callback_def = deadline_data [DeadlineAlertFields .CALLBACK ],
@@ -625,6 +635,7 @@ def write_dag(
625635 serialized_dag_hash = _prefetched .dag_hash
626636 dag_version = _prefetched .dag_version
627637
638+ name_updated = False
628639 if dag .data .get ("dag" , {}).get ("deadline" ):
629640 # Try to reuse existing deadline UUIDs if the deadline definitions haven't changed.
630641 # This preserves the hash and avoids unnecessary SerializedDagModel recreations.
@@ -637,16 +648,24 @@ def write_dag(
637648 and existing_serialized_dag .data
638649 and (existing_deadline_uuids := existing_serialized_dag .data .get ("dag" , {}).get ("deadline" ))
639650 ):
640- deadline_uuid_mapping = cls ._try_reuse_deadline_uuids (
651+ reuse_result = cls ._try_reuse_deadline_uuids (
641652 existing_deadline_uuids ,
642653 dag .data ["dag" ]["deadline" ],
643654 session ,
644655 )
645656
646- if deadline_uuid_mapping is not None :
657+ if reuse_result is not None :
658+ deadline_uuid_mapping , name_updates = reuse_result
647659 # All deadlines matched — reuse the UUIDs to preserve hash.
648- # Clear the mapping since the alert rows already exist in the DB;
649- # no need to delete and recreate identical records.
660+ # Only issue UPDATE statements for rows whose name actually changed to
661+ # avoid unnecessary writes and to make the return value accurate.
662+ for uuid_str , new_name in name_updates .items ():
663+ session .execute (
664+ update (DeadlineAlertModel )
665+ .where (DeadlineAlertModel .id == UUID (uuid_str ))
666+ .values (name = new_name )
667+ )
668+ name_updated = bool (name_updates )
650669 dag .data ["dag" ]["deadline" ] = existing_deadline_uuids
651670 deadline_uuid_mapping = {}
652671 else :
@@ -665,6 +684,10 @@ def write_dag(
665684 and dag_version
666685 and dag_version .bundle_name == bundle_name
667686 ):
687+ if name_updated :
688+ # The serialized DAG itself is unchanged, but deadline alert name(s) were
689+ # updated in the DB, so report True so callers know a write did occur.
690+ return True
668691 log .debug ("Serialized DAG (%s) is unchanged. Skipping writing to DB" , dag .dag_id )
669692 return False
670693
0 commit comments