@@ -16,7 +16,15 @@ class HierarchyNode(BaseModel):
1616 """Stores entity hierarchy information"""
1717
1818 entity_name : str
19- children : Optional [list ["ChildHierarchyNode" ]] = Field (default_factory = list )
19+ children : list ["HierarchyNode" ] = Field (default_factory = list )
20+ mandatory : bool = False
21+ join_fields : dict [str , str ] = Field (default_factory = dict )
22+ no_valid_records_error_code : ErrorCode = "NoValidRecords"
23+ no_valid_records_error_message : ErrorMessage = "parent record removed as no valid child records"
24+ missing_parent_id_error_code : Optional [ErrorCode ] = "MissingParentRecord"
25+ missing_parent_id_error_message : Optional [ErrorMessage ] = (
26+ "Records removed due to no valid parent record"
27+ )
2028
2129 def get_descendents (self ) -> list [str ]:
2230 """Recursively list all descendents of the node"""
@@ -58,19 +66,6 @@ def as_dict(self) -> dict[str, dict[str, Any]]:
5866 return {self .entity_name : ret_dict }
5967
6068
61- class ChildHierarchyNode (HierarchyNode ):
62- """Stores child entity hierarchy information"""
63-
64- join_fields : dict [str , str ]
65- mandatory : Optional [bool ] = False
66- no_valid_records_error_code : Optional [ErrorCode ] = "NoValidRecords"
67- no_valid_records_error_message : Optional [ErrorMessage ] = (
68- "parent record removed as no valid child records"
69- )
70- orphaned_records_error_code : Optional [ErrorCode ] = "OrphanedRecords"
71- orphaned_records_error_message : Optional [ErrorMessage ] = "Orphaned records removed"
72-
73-
7469class EntityHierarchy :
7570 """Determines and stores entity hierarchy information from config"""
7671
@@ -82,12 +77,35 @@ def determine_trees(
8277 all_datasets : Iterable [str ], entity_relationships : dict [str , _LinkageConfig ]
8378 ) -> dict [EntityName , HierarchyNode ]:
8479 """Determine the entity hierarchy trees and store as HierarchyNodes"""
80+ root_entities : dict [str , _LinkageConfig ] = dict (
81+ filter (lambda x : x [1 ].is_root_entity , entity_relationships .items ())
82+ )
8583 top_level_parents : dict [EntityName , HierarchyNode ] = {
86- entity_name : HierarchyNode (entity_name = entity_name )
87- for entity_name in all_datasets
88- if entity_name not in entity_relationships
84+ entity_name : HierarchyNode (
85+ entity_name = entity_name ,
86+ ** config .model_dump (
87+ exclude = {
88+ "parent_entity" ,
89+ "missing_parent_id_error_code" ,
90+ "missing_parent_id_error_message" ,
91+ }
92+ ),
93+ missing_parent_id_error_code = None ,
94+ missing_parent_id_error_message = None ,
95+ )
96+ for entity_name , config in root_entities .items ()
8997 }
9098
99+ if default_roots := [
100+ entity_name for entity_name in all_datasets if entity_name not in entity_relationships
101+ ]:
102+ for entity_name in default_roots :
103+ top_level_parents [entity_name ] = HierarchyNode (
104+ entity_name = entity_name ,
105+ missing_parent_id_error_code = None ,
106+ missing_parent_id_error_message = None ,
107+ )
108+
91109 for name , linkage_detail in entity_relationships .items ():
92110 for main_entity , parent_node in top_level_parents .items ():
93111 if (
@@ -96,7 +114,7 @@ def determine_trees(
96114 ):
97115 parent_node .add_child_node (
98116 linkage_detail .parent_entity ,
99- ChildHierarchyNode (
117+ HierarchyNode (
100118 entity_name = name , ** linkage_detail .model_dump (exclude = {"parent_entity" })
101119 ),
102120 )
0 commit comments