Skip to content

Commit 1590311

Browse files
Mr-SabyasachiBoseMariusWirtz
authored andcommitted
Allow a list of consolidations to be unwound
for update_or_create_hierarchy_from_dataframe function Currently update_or_create_hierarchy_from_dataframe() allows complete unwinding of hierarchy, but not specific unwinding for consolidations. The code change would allow a list of elements to be specified a parameter so selective unwinding is allowed. This change also replace the param unwind with unwind_all, used for same purpose. Function is updated to be backward compatible so, using unwind would map the value to unwind_all and continue unwinding the entire hierarchy when True.
1 parent fad99fb commit 1590311

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

TM1py/Services/HierarchyService.py

+33-5
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,10 @@ def update_or_create_hierarchy_from_dataframe(
427427
verify_unique_elements: bool = False,
428428
verify_edges: bool = True,
429429
element_type_column: str = 'ElementType',
430-
unwind: bool = False,
431-
update_attribute_types: bool = False):
430+
unwind_all: bool = False,
431+
unwind_consolidation: list = None,
432+
update_attribute_types: bool = False,
433+
**kwargs):
432434
""" Update or Create a hierarchy based on a dataframe, while never deleting existing elements.
433435
434436
:param dimension_name:
@@ -455,8 +457,10 @@ def update_or_create_hierarchy_from_dataframe(
455457
Abort early if element names are not unique
456458
:param verify_edges:
457459
Abort early if edges contain a circular reference
458-
:param unwind: bool
460+
:param unwind_all: bool
459461
Unwind hierarch before creating new edges
462+
:param unwind_consolidation: list
463+
Unwind a list specific consolidations in hierarch before creating new edges, if unwind_all is true, this list is ignored
460464
:param update_attribute_types: bool
461465
If True, function will delete and recreate attributes when a type change is requested.
462466
By default, function will not delete attributes.
@@ -485,6 +489,15 @@ def update_or_create_hierarchy_from_dataframe(
485489
if len(alias_columns) > 0:
486490
self._validate_alias_uniqueness(df=df[[element_column, *alias_columns]])
487491

492+
# backward compatibility for unwind, the value for unwind would be assinged to unwind_all. expected type is bool
493+
if "unwind" in kwargs:
494+
unwind_all = kwargs["unwind"]
495+
496+
# verify unwind_consolidation is a list
497+
if unwind_consolidation is not None:
498+
if not isinstance(unwind_consolidation, list):
499+
raise ValueError(f"Inconsistent Type for 'unwind_consolidation': expected type-> list, current type-> '{type(unwind_consolidation)}'")
500+
488501
# identify and sort level columns
489502
level_columns = []
490503
level_weight_columns = []
@@ -634,8 +647,23 @@ def update_or_create_hierarchy_from_dataframe(
634647
sum_numeric_duplicates=False,
635648
use_blob=True)
636649

637-
if unwind:
638-
self.remove_all_edges(dimension_name, hierarchy_name)
650+
if unwind_all:
651+
self.remove_all_edges(dimension_name=dimension_name, hierarchy_name=hierarchy_name)
652+
else:
653+
if unwind_consolidation is not None:
654+
all_edges = CaseAndSpaceInsensitiveTuplesDict()
655+
for elem in unwind_consolidation:
656+
if self.elements.exists(dimension_name=dimension_name, hierarchy_name=hierarchy_name, element_name=elem):
657+
temp_edges = self.elements.get_edges_under_consolidation(
658+
dimension_name=dimension_name,
659+
hierarchy_name=hierarchy_name,
660+
consolidation=elem)
661+
all_edges.join(temp_edges)
662+
self.elements.delete_edges(
663+
dimension_name=dimension_name,
664+
hierarchy_name=hierarchy_name,
665+
edges=all_edges,
666+
use_ti=self.is_admin)
639667

640668
edges = CaseAndSpaceInsensitiveTuplesDict()
641669
for element_name, *record in df[[element_column, *level_columns, *level_weight_columns]].itertuples(

TM1py/Utils/Utils.py

+8
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,14 @@ def __eq__(self, other):
11751175
def copy(self):
11761176
return CaseAndSpaceInsensitiveTuplesDict(self._store.values())
11771177

1178+
# Join two dictionaries together
1179+
def join(self, other):
1180+
if isinstance(other, CaseAndSpaceInsensitiveTuplesDict):
1181+
for key,value in other.items():
1182+
self._store[tuple([lower_and_drop_spaces(item) for item in key])] = (key, value)
1183+
else:
1184+
raise ValueError("Other object is not of type CaseAndSpaceInsensitiveTuplesDict")
1185+
11781186
def __repr__(self):
11791187
return str(dict(self.items()))
11801188

0 commit comments

Comments
 (0)