@@ -387,119 +387,107 @@ def identify_and_remove_orphans(
387387 entities : Entities ,
388388 entity_hierarchy : EntityHierarchy ,
389389 key_fields : Optional [dict [str , list [str ]]] = None ,
390- ) -> tuple [Messages , bool ]:
390+ ) -> tuple [Messages , dict [ EntityName , bool ] ]:
391391 """
392392 Identifies and removes orphan records by traversing the EntityHierarchy object.
393393 An orphan is a child record whose parent FK does not exist in the parent entity.
394394 Processes recursively: removes orphans at each level, then processes children.
395395 """
396396
397- def process_node (
398- node : HierarchyNode ,
399- orph_messages : Messages | None = None ,
400- processed : bool = False ,
401- ):
397+ def process_node (node : HierarchyNode ):
402398 """Identify orphans and remove in a given node"""
399+ issues_found : bool = False
400+ if node .parent_entity is None :
401+ return issues_found
403402
404- if orph_messages is None :
405- orph_messages = []
403+ self .logger .info (f"Identifying orphans in { node .entity_name } " )
406404
407- if node .parent_entity is not None :
408- self .logger .info (f"Identifying orphans in { node .entity_name } " )
409-
410- join_expr = " AND " .join (
411- f"{ node .parent_entity } .{ k } = { node .entity_name } .{ v } "
412- for k , v in node .join_fields .items ()
413- )
405+ join_expr = " AND " .join (
406+ f"{ node .parent_entity } .{ k } = { node .entity_name } .{ v } "
407+ for k , v in node .join_fields .items ()
408+ )
414409
415- _ , no_orphs = self .identify_orphans (
416- entities = entities ,
417- config = OrphanIdentification (
418- id = list (node .join_fields .values ())[0 ],
419- entity_name = node .entity_name ,
420- target_name = node .parent_entity ,
421- join_condition = join_expr ,
422- ),
423- )
410+ _ , no_orphs = self .identify_orphans (
411+ entities = entities ,
412+ config = OrphanIdentification (
413+ id = list (node .join_fields .values ())[0 ],
414+ entity_name = node .entity_name ,
415+ target_name = node .parent_entity ,
416+ join_condition = join_expr ,
417+ ),
418+ )
424419
425- if no_orphs > 0 :
426- self .logger .info (
427- f"Removing records with missing parent from { node .entity_name } "
428- )
429- processed = True
430- location = list (node .join_fields .values ())[0 ]
431- with BackgroundMessageWriter (
432- working_directory = working_directory ,
433- dve_stage = self .__stage_name__ ,
434- key_fields = key_fields ,
435- logger = self .logger ,
436- ) as msg_writer :
437- _orph_records = self .remove_orphans (
438- entities = entities ,
439- config = OrphanRemoval (
440- entity_name = node .entity_name ,
441- reporting = ReportingConfig (
442- emit = "record_failure" ,
443- code = node .missing_parent_id_error_code ,
444- message = node .missing_parent_id_error_message ,
445- location = location ,
446- ),
420+ if no_orphs > 0 :
421+ self .logger .info (f"Removing records with missing parent from { node .entity_name } " )
422+ issues_found = True
423+ location = list (node .join_fields .values ())[0 ]
424+ with BackgroundMessageWriter (
425+ working_directory = working_directory ,
426+ dve_stage = self .__stage_name__ ,
427+ key_fields = key_fields ,
428+ logger = self .logger ,
429+ ) as msg_writer :
430+ _orph_records = self .remove_orphans (
431+ entities = entities ,
432+ config = OrphanRemoval (
433+ entity_name = node .entity_name ,
434+ reporting = ReportingConfig (
435+ emit = "record_failure" ,
436+ code = node .missing_parent_id_error_code ,
437+ message = node .missing_parent_id_error_message ,
438+ location = location ,
447439 ),
448- )
449- # moved to batch the write - risky if large number of
450- msg_writer .write_queue .put (
451- [
452- FeedbackMessage (
453- entity = node .entity_name ,
454- record = record , # type: ignore
455- error_location = location ,
456- error_message = node .missing_parent_id_error_message ,
457- failure_type = "record" ,
458- error_type = "record" ,
459- error_code = node .missing_parent_id_error_code ,
460- reporting_field = location ,
461- category = "Parent Missing" ,
462- )
463- for record in _orph_records
464- ]
465- )
440+ ),
441+ )
442+ # moved to batch the write - risky if large number of
443+ msg_writer .write_queue .put (
444+ [
445+ FeedbackMessage (
446+ entity = node .entity_name ,
447+ record = record , # type: ignore
448+ error_location = location ,
449+ error_message = node .missing_parent_id_error_message ,
450+ failure_type = "record" ,
451+ error_type = "record" ,
452+ error_code = node .missing_parent_id_error_code ,
453+ reporting_field = location ,
454+ category = "Parent Missing" ,
455+ )
456+ for record in _orph_records
457+ ]
458+ )
466459
467- return processed
460+ return issues_found
468461
469- processed = False
462+ entity_issues_found : dict [ EntityName , bool ] = {}
470463
471464 for tree in entity_hierarchy .entity_trees .values ():
472465 for node in tree .iterate_root_down ():
473- processed = process_node (node )
466+ entity_issues_found [ node . entity_name ] = process_node (node )
474467
475468 _orph_rel = entities .get (ORPHANED_RECORD_ENTITY_NAME )
476469 if _orph_rel is not None :
477470 del entities [ORPHANED_RECORD_ENTITY_NAME ]
478471
479472 entities .update (entities )
480473
481- return [], processed
474+ return [], entity_issues_found
482475
483476 def identify_and_remove_missing_mandatory_groups (
484477 self ,
485478 working_directory : URI ,
486479 entities : Entities ,
487480 entity_hierarchy : EntityHierarchy ,
488481 key_fields : Optional [dict [str , list [str ]]] = None ,
489- ) -> tuple [Messages , bool ]:
482+ ) -> tuple [Messages , dict [ EntityName , bool ] ]:
490483 """
491484 Identify that an entity with a mandatory key has at least one valid child record.
492485 """
493486
494- def process_node (
495- node : HierarchyNode ,
496- processed : bool = False ,
497- ) -> bool :
487+ def process_node (node : HierarchyNode ) -> bool :
498488 """Identify at least one valid child for a mandatory entity at a given node."""
499489 if node .parent_entity is None or not node .mandatory :
500- return processed
501-
502- processed = True
490+ return False
503491
504492 self .logger .info (
505493 f"Identifying that mandatory entity `{ node .parent_entity } ` has at least 1 valid child record" # pylint: disable=C0301
@@ -525,34 +513,33 @@ def process_node(
525513 join_condition = join_expr ,
526514 ),
527515 )
528- for record in missing_children_records :
529- msg_writer .write_queue .put (
530- [
531- FeedbackMessage (
532- entity = node .parent_entity ,
533- record = record , # type: ignore
534- error_location = location ,
535- error_message = node .no_valid_records_error_message ,
536- failure_type = "record" ,
537- error_type = "record" ,
538- error_code = node .no_valid_records_error_code ,
539- reporting_field = location ,
540- category = "Children missing" ,
541- )
542- ]
516+ _messages = [
517+ FeedbackMessage (
518+ entity = node .parent_entity ,
519+ record = record , # type: ignore
520+ error_location = location ,
521+ error_message = node .no_valid_records_error_message ,
522+ failure_type = "record" ,
523+ error_type = "record" ,
524+ error_code = node .no_valid_records_error_code ,
525+ reporting_field = location ,
526+ category = "Children missing" ,
543527 )
528+ for record in missing_children_records
529+ ]
530+ msg_writer .write_queue .put (_messages )
531+ return len (_messages ) > 0
544532
545- return processed
546-
547- processed = False
533+ entity_issues_found : dict [EntityName , bool ] = {}
548534
549535 for tree in entity_hierarchy .entity_trees .values ():
550536 for node in tree .iterate_lowest_descendent_up ():
551- processed = process_node (node , processed )
537+ if node .parent_entity and node .mandatory :
538+ entity_issues_found [node .parent_entity ] = process_node (node )
552539
553- entities .update (entities )
540+ # entities.update(entities)
554541
555- return [], processed
542+ return [], entity_issues_found
556543
557544 # pylint: disable=R0912,R0914
558545 def apply_sync_filters (
0 commit comments