def __init__(self, rest): super().__init__(rest) self.elements = ElementService(rest)
class HierarchyService(ObjectService): """ Service to handle Object Updates for TM1 Hierarchies """ def __init__(self, rest): super().__init__(rest) self.elements = ElementService(rest) def create(self, hierarchy): """ Create a hierarchy in an existing dimension :param hierarchy: :return: """ raise NotImplementedError('not supported') def get(self, dimension_name, hierarchy_name): """ get hierarchy :param dimension_name: name of the dimension :param hierarchy_name: name of the hierarchy :return: """ request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format( dimension_name, hierarchy_name) response = self._rest.GET(request, '') return response def update(self, hierarchy): """ update a hierarchy. Is a two step process. 1. Update Hierarchy 2. Update Element-Attributes :param hierarchy: instance of TM1py.Hierarchy :return: """ # Update Hierarchy request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format( hierarchy.dimension_name, hierarchy.name) response = self._rest.PATCH(request, hierarchy.body) # Update Attributes self._update_element_attributes(hierarchy=hierarchy) return response def exists(self, dimension_name, hierarchy_name): """ :param dimension_name: :param hierarchy_name: :return: """ request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format( dimension_name, hierarchy_name) return super(HierarchyService, self).exists(request) def delete(self, dimension_name, hierarchy_name): request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format( dimension_name, hierarchy_name) return self._rest.DELETE(request) def _update_element_attributes(self, hierarchy): """ Update the element sattributes of a hierarchy :param hierarchy: Instance of TM1py.Hierarchy :return: """ # get existing attributes first. element_attributes = self.elements.get_element_attributes( dimension_name=hierarchy.dimension_name, hierarchy_name=hierarchy.name) element_attribute_names = [ea.name for ea in element_attributes] # write ElementAttributes that don't already exist ! for element_attribute in hierarchy.element_attributes: if element_attribute not in element_attribute_names: self.elements.create_element_attribute( dimension_name=hierarchy.dimension_name, hierarchy_name=hierarchy.name, element_attribute=element_attribute) # delete attributes that are determined to be removed for element_attribute in element_attribute_names: if element_attribute not in hierarchy.element_attributes: self.elements.delete_element_attribute( dimension_name=hierarchy.dimension_name, hierarchy_name=hierarchy.name, element_attribute=element_attribute)
class HierarchyService(ObjectService): """ Service to handle Object Updates for TM1 Hierarchies """ # Tuple with TM1 Versions where Edges need to be created through TI, due to bug: # https://www.ibm.com/developerworks/community/forums/html/topic?id=75f2b99e-6961-4c71-9364-1d5e1e083eff EDGES_WORKAROUND_VERSIONS = ('11.0.002', '11.0.003', '11.1.000') def __init__(self, rest): super().__init__(rest) self.subsets = SubsetService(rest) self.elements = ElementService(rest) def create(self, hierarchy): """ Create a hierarchy in an existing dimension :param hierarchy: :return: """ request = '/api/v1/Dimensions(\'{}\')/Hierarchies'.format(hierarchy.dimension_name) response = self._rest.POST(request, hierarchy.body) return response def get(self, dimension_name, hierarchy_name): """ get hierarchy :param dimension_name: name of the dimension :param hierarchy_name: name of the hierarchy :return: """ request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')?$expand=Edges,Elements,ElementAttributes,Subsets,DefaultMember'\ .format(dimension_name, hierarchy_name) response = self._rest.GET(request, '') return Hierarchy.from_dict(response.json()) def update(self, hierarchy): """ update a hierarchy. It's a two step process: 1. Update Hierarchy 2. Update Element-Attributes Function caters for Bug with Edge Creation: https://www.ibm.com/developerworks/community/forums/html/topic?id=75f2b99e-6961-4c71-9364-1d5e1e083eff :param hierarchy: instance of TM1py.Hierarchy :return: list of responses """ # functions returns multiple responses responses = list() # 1. Update Hierarchy request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format(hierarchy.dimension_name, hierarchy.name) # Workaround EDGES: Handle Issue, that Edges cant be created in one batch with the Hierarchy in certain versions hierarchy_body = hierarchy.body_as_dict if self.version[0:8] in self.EDGES_WORKAROUND_VERSIONS: del hierarchy_body["Edges"] responses.append(self._rest.PATCH(request, json.dumps(hierarchy_body))) # 2. Update Attributes responses.append(self._update_element_attributes(hierarchy=hierarchy)) # Workaround EDGES if self.version[0:8] in self.EDGES_WORKAROUND_VERSIONS: from TM1py.Services import ProcessService process_service = ProcessService(self._rest) ti_function = "HierarchyElementComponentAdd('{}', '{}', '{}', '{}', {});" ti_statements = [ti_function.format(hierarchy.dimension_name, hierarchy.name, edge[0], edge[1], hierarchy.edges[(edge[0], edge[1])]) for edge in hierarchy.edges] lines_prolog = ''.join(ti_statements) responses.append(process_service.execute_ti_code(lines_prolog=lines_prolog)) return responses def exists(self, dimension_name, hierarchy_name): """ :param dimension_name: :param hierarchy_name: :return: """ request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format(dimension_name, hierarchy_name) return self._exists(request) def delete(self, dimension_name, hierarchy_name): request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')'.format(dimension_name, hierarchy_name) return self._rest.DELETE(request) def get_hierarchy_summary(self, dimension_name, hierarchy_name): hierarchy_properties = ("Elements", "Edges", "ElementAttributes", "Members", "Levels") request = "/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')?$expand=Edges/$count,Elements/$count," \ "ElementAttributes/$count,Members/$count,Levels/$count&$select=Cardinality"\ .format(dimension_name, hierarchy_name) hierary_summary_raw = self._rest.GET(request).json() return {hierarchy_property: hierary_summary_raw[hierarchy_property + "@odata.count"] for hierarchy_property in hierarchy_properties} def _update_element_attributes(self, hierarchy): """ Update the elementattributes of a hierarchy :param hierarchy: Instance of TM1py.Hierarchy :return: """ # get existing attributes first. element_attributes = self.elements.get_element_attributes(dimension_name=hierarchy.dimension_name, hierarchy_name=hierarchy.name) element_attribute_names = [ea.name for ea in element_attributes] # write ElementAttributes that don't already exist ! for element_attribute in hierarchy.element_attributes: if element_attribute not in element_attribute_names: self.elements.create_element_attribute(dimension_name=hierarchy.dimension_name, hierarchy_name=hierarchy.name, element_attribute=element_attribute) # delete attributes that are determined to be removed for element_attribute in element_attribute_names: if element_attribute not in hierarchy.element_attributes: self.elements.delete_element_attribute(dimension_name=hierarchy.dimension_name, hierarchy_name=hierarchy.name, element_attribute=element_attribute)