@@ -136,32 +136,74 @@ def delete_edges(
136136 use_ti : bool = False ,
137137 use_blob : bool = False ,
138138 remove_blob : bool = True ,
139+ skip_invalid_edges : bool = True ,
139140 ** kwargs ,
140141 ):
142+ """
143+ Remove edges in TM1.
144+
145+ :param dimension_name: The name of the dimension.
146+ :param hierarchy_name: The name of the hierarchy.
147+ :param edges: A list of tuples representing the edges to remove, where each tuple contains a parent and a child.
148+ :param use_ti: A boolean indicating whether to use a TI process to delete edges (default: False).
149+ :param use_blob: A boolean indicating whether to use a blob file to delete edges (default: False).
150+ :param remove_blob: A boolean indicating whether to remove the parent-child file after use (default: True).
151+ :param skip_invalid_edges: A boolean indicating whether to skip invalid edges (default: True).
152+ """
141153 if use_ti :
142- return self .delete_edges_use_ti (dimension_name , hierarchy_name , edges , ** kwargs )
154+ return self .delete_edges_use_ti (dimension_name , hierarchy_name , edges , skip_invalid_edges , ** kwargs )
143155
144156 if use_blob :
145- return self .delete_edges_use_blob (dimension_name , hierarchy_name , edges , remove_blob , ** kwargs )
157+ return self .delete_edges_use_blob (
158+ dimension_name , hierarchy_name , edges , remove_blob , skip_invalid_edges , ** kwargs
159+ )
146160
147161 h_service = self ._get_hierarchy_service ()
148162 h = h_service .get (dimension_name , hierarchy_name , ** kwargs )
149163 for edge in edges :
164+ if edge not in h .edges and not skip_invalid_edges :
165+ raise TM1pyException (f"Edge { edge } does not exist in hierarchy [{ dimension_name } ].[{ hierarchy_name } ]" )
150166 h .remove_edge (parent = edge [0 ], component = edge [1 ])
151167 h_service .update (h , ** kwargs )
152168
153- def delete_edges_use_ti (self , dimension_name : str , hierarchy_name : str , edges : List [str ] = None , ** kwargs ):
169+ def delete_edges_use_ti (
170+ self ,
171+ dimension_name : str ,
172+ hierarchy_name : str ,
173+ edges : List [str ] = None ,
174+ skip_invalid_edges : bool = True ,
175+ ** kwargs ,
176+ ):
177+ """
178+ Remove edges in TM1 via an unbound TI process.
179+ :param dimension_name: The name of the dimension.
180+ :param hierarchy_name: The name of the hierarchy.
181+ :param edges: A list of tuples representing the edges to remove, where each tuple contains a parent and a child.
182+ :param skip_invalid_edges: A boolean indicating whether to skip invalid edges (default: True).
183+ """
154184 if not edges :
155185 return
156186
157187 def escape_single_quote (text ):
158188 return text .replace ("'" , "''" )
159189
160- statements = [
161- f"HierarchyElementComponentDelete('{ dimension_name } ', '{ hierarchy_name } ', "
162- f"'{ escape_single_quote (parent )} ', '{ escape_single_quote (child )} ');"
163- for (parent , child ) in edges
164- ]
190+ statements = []
191+ for parent , child in edges :
192+ parent = escape_single_quote (parent )
193+ child = escape_single_quote (child )
194+ if skip_invalid_edges :
195+ statements .extend (
196+ [
197+ f"IF(ElementIsParent('{ dimension_name } ','{ hierarchy_name } ','{ parent } ','{ child } ')=1);" ,
198+ f"HierarchyElementComponentDelete('{ dimension_name } ','{ hierarchy_name } ','{ parent } ','{ child } ');" ,
199+ f"ENDIF;" ,
200+ ]
201+ )
202+
203+ else :
204+ statements .append (
205+ f"HierarchyElementComponentDelete('{ dimension_name } ', '{ hierarchy_name } ', '{ parent } ', '{ child } ');"
206+ )
165207
166208 unbound_process_name = self .suggest_unique_object_name ()
167209
@@ -174,7 +216,13 @@ def escape_single_quote(text):
174216 @require_data_admin
175217 @require_ops_admin
176218 def delete_edges_use_blob (
177- self , dimension_name : str , hierarchy_name : str , edges : List [str ] = None , remove_blob : bool = True , ** kwargs
219+ self ,
220+ dimension_name : str ,
221+ hierarchy_name : str ,
222+ edges : List [str ] = None ,
223+ remove_blob : bool = True ,
224+ skip_invalid_edges : bool = True ,
225+ ** kwargs ,
178226 ):
179227 """
180228 Remove edges in TM1 via an unbound TI process having an uploaded CSV as the data source.
@@ -183,6 +231,7 @@ def delete_edges_use_blob(
183231 :param hierarchy_name: The name of the hierarchy.
184232 :param edges: A list of tuples representing the edges to remove, where each tuple contains a parent and a child.
185233 :param remove_blob: A boolean indicating whether to remove the parent-child file after use (default: True).
234+ :param skip_invalid_edges: A boolean indicating whether to skip invalid edges (default: True).
186235 :param kwargs: Additional arguments for the process execution.
187236 :return: None
188237 """
@@ -209,6 +258,7 @@ def delete_edges_use_blob(
209258 hierarchy_name = hierarchy_name ,
210259 process_name = unique_name ,
211260 blob_filename = file_name ,
261+ skip_invalid_edges = skip_invalid_edges ,
212262 )
213263
214264 success , status , log_file = process_service .execute_process_with_return (process = process , ** kwargs )
@@ -223,7 +273,12 @@ def delete_edges_use_blob(
223273 file_service .delete (file_name = file_name )
224274
225275 def _build_unwind_hierarchy_edges_from_blob_process (
226- self , dimension_name : str , hierarchy_name : str , process_name : str , blob_filename : str
276+ self ,
277+ dimension_name : str ,
278+ hierarchy_name : str ,
279+ process_name : str ,
280+ blob_filename : str ,
281+ skip_invalid_edges : bool = True ,
227282 ) -> Process :
228283
229284 # v11 automatically adds blb file extensions to documents created via the contents api
@@ -251,7 +306,15 @@ def _build_unwind_hierarchy_edges_from_blob_process(
251306 hierarchyupdate_process .add_variable (name = child_variable , variable_type = "String" )
252307
253308 # Write the statement for delete component in hierarchy
254- delete_component = f"\r HierarchyElementComponentDelete('{ dimension_name } ', '{ hierarchy_name } ', { parent_variable } , { child_variable } );"
309+ if skip_invalid_edges :
310+ delete_component = (
311+ f"\r "
312+ f"IF(ElementIsParent('{ dimension_name } ','{ hierarchy_name } ',{ parent_variable } ,{ child_variable } )=1);"
313+ f"HierarchyElementComponentDelete('{ dimension_name } ','{ hierarchy_name } ',{ parent_variable } ,{ child_variable } );"
314+ f"ENDIF;"
315+ )
316+ else :
317+ delete_component = f"HierarchyElementComponentDelete('{ dimension_name } ','{ hierarchy_name } ',{ parent_variable } ,{ child_variable } );"
255318
256319 # Define Metadata section
257320 metadata_statement = delete_component
0 commit comments