def write_values(self, cube_name, cellset_as_dict, dimensions=None): """ Write values in cube. For cellsets with > 1000 cells look into "write_values_through_cellset" :param cube_name: name of the cube :param cellset_as_dict: {(elem_a, elem_b, elem_c): 243, (elem_d, elem_e, elem_f) : 109} :param dimensions: optional. Dimension names in their natural order. Will speed up the execution! :return: Response """ if not dimensions: from TM1py.Services import CubeService cube_service = CubeService(self._rest) dimensions = cube_service.get_dimension_names(cube_name) request = "/api/v1/Cubes('{}')/tm1.Update".format(cube_name) updates = [] for element_tuple, value in cellset_as_dict.items(): body_as_dict = collections.OrderedDict() body_as_dict["Cells"] = [{}] body_as_dict["Cells"][0]["*****@*****.**"] = \ ["Dimensions('{}')/Hierarchies('{}')/Elements('{}')".format(dim, dim, elem) for dim, elem in zip(dimensions, element_tuple)] body_as_dict["Value"] = str(value) if value else "" updates.append(json.dumps(body_as_dict, ensure_ascii=False)) updates = '[' + ','.join(updates) + ']' return self._rest.POST(request=request, data=updates)
def get_dimension_names_for_writing(self, cube_name): from TM1py.Services import CubeService cube_service = CubeService(self._rest) dimensions = cube_service.get_dimension_names(cube_name) # do not return sandbox dimension as first dimension, as it can't be used in address tuple for writing if case_and_space_insensitive_equals(dimensions[0], self.SANDBOX_DIMENSION): return dimensions[1:] return dimensions
def get_value(self, cube_name, element_string, dimensions=None): """ Element_String describes the Dimension-Hierarchy-Element arrangement :param cube_name: Name of the cube :param element_string: "Hierarchy1::Element1 && Hierarchy2::Element4, Element9, Element2" - Dimensions are not specified! They are derived from the position. - The , seperates the element-selections - If more than one hierarchy is selected per dimension && splits the elementselections - If no Hierarchy is specified. Default Hierarchy will be addressed :param dimensions: List of dimension names in correct order :return: """ mdx_template = "SELECT {} ON ROWS, {} ON COLUMNS FROM [{}]" mdx_rows_list = [] from TM1py.Services.CubeService import CubeService if not dimensions: dimensions = CubeService(self._rest).get(cube_name).dimensions element_selections = element_string.split(',') # Build the ON ROWS statement: # Loop through the comma seperated element selection, except for the last one for dimension_name, element_selection in zip(dimensions[:-1], element_selections[:-1]): if "&&" not in element_selection: mdx_rows_list.append("{[" + dimension_name + "].[" + dimension_name + "].[" + element_selection + "]}") else: for element_selection_part in element_selection.split('&&'): hierarchy_name, element_name = element_selection_part.split( '::') mdx_rows_list.append("{[" + dimension_name + "].[" + hierarchy_name + "].[" + element_name + "]}") mdx_rows = "*".join(mdx_rows_list) # Build the ON COLUMNS statement from last dimension mdx_columns = "" if "&&" not in element_selections[-1]: mdx_columns = "{[" + dimensions[-1] + "].[" + dimensions[ -1] + "].[" + element_selections[-1] + "]}" else: mdx_columns_list = [] for element_selection_part in element_selections[-1].split('&&'): hierarchy_name, element_name = element_selection_part.split( '::') mdx_columns_list.append("{[" + dimensions[-1] + "].[" + hierarchy_name + "].[" + element_name + "]}") mdx_columns = "*".join(mdx_columns_list) # Construct final MDX mdx = mdx_template.format(mdx_rows, mdx_columns, cube_name) # Execute MDX cellset = dict(self.execute_mdx(mdx)) return next(iter(cellset.values()))["Value"]
def write_values(self, cube_name, cellset_as_dict): """ Write values in cube. Easy to use but doesnt scale. Not suitable for cellsets with > 1000 cells :param cube_name: name of the cube :param cellset_as_dict: {(elem_a, elem_b, elem_c): 243, (elem_d, elem_e, elem_f) : 109} :return: """ cube_service = CubeService(self._rest) dimension_order = cube_service.get_dimension_names(cube_name) request = "/api/v1/Cubes('{}')/tm1.Update".format(cube_name) updates = [] for element_tuple, value in cellset_as_dict.items(): body_as_dict = collections.OrderedDict() body_as_dict["Cells"] = [{}] body_as_dict["Cells"][0]["*****@*****.**"] = \ ["Dimensions('{}')/Hierarchies('{}')/Elements('{}')".format(dim, dim, elem) for dim, elem in zip(dimension_order, element_tuple)] body_as_dict["Value"] = str(value) updates.append(json.dumps(body_as_dict, ensure_ascii=False)) updates = '[' + ','.join(updates) + ']' self._rest.POST(request=request, data=updates)
def write_value(self, value, cube_name, element_tuple, dimensions=None): """ Write value into cube at specified coordinates :param value: the actual value :param cube_name: name of the target cube :param element_tuple: target coordinates :param dimensions: optional. Dimension names in their natural order. Will speed up the request! :return: response """ if not dimensions: dimensions = CubeService(self._rest).get(cube_name).dimensions request = "/api/v1/Cubes('{}')/tm1.Update".format(cube_name) body_as_dict = collections.OrderedDict() body_as_dict["Cells"] = [{}] body_as_dict["Cells"][0]["*****@*****.**"] = \ ["Dimensions('{}')/Hierarchies('{}')/Elements('{}')".format(dim, dim, elem) for dim, elem in zip(dimensions, element_tuple)] body_as_dict["Value"] = str(value) data = json.dumps(body_as_dict, ensure_ascii=False) return self._rest.POST(request=request, data=data)
def __init__(self, rest): super().__init__(rest) self._cube_service = CubeService(rest)
class AnnotationService(ObjectService): """ Service to handle Object Updates for TM1 CellAnnotations """ def __init__(self, rest): super().__init__(rest) self._cube_service = CubeService(rest) def get_all(self, cube_name): """ get all annotations from given cube as a List. :param cube_name: :return: list of instances of TM1py.Annotation """ request = "/api/v1/Cubes('{}')/Annotations?$expand=DimensionalContext($select=Name)".format(cube_name) response = self._rest.GET(request, '') annotations_as_dict = json.loads(response)['value'] annotations = [Annotation.from_json(json.dumps(element)) for element in annotations_as_dict] return annotations def create(self, annotation): """ create an Annotation :param annotation: instance of TM1py.Annotation :return string: the response """ request = "/api/v1/Annotations" payload = collections.OrderedDict() payload["Text"] = annotation.text payload["ApplicationContext"] = [{"*****@*****.**": "ApplicationContextFacets('}Cubes')", "Value": annotation.object_name}] payload["*****@*****.**"] = [] for dimension, element in zip(self._cube_service.get_dimension_names(annotation.object_name), annotation.dimensional_context): payload["*****@*****.**"].append("Dimensions('{}')/Hierarchies('{}')/Members('{}')" .format(dimension, dimension, element)) payload['objectName'] = annotation.object_name payload['commentValue'] = annotation.comment_value payload['commentType'] = 'ANNOTATION' payload['commentLocation'] = ','.join(annotation.dimensional_context) response = self._rest.POST(request, json.dumps(payload, ensure_ascii=False)) return response def get(self, annotation_id): """ get an annotation from any cube in TM1 Server through its id :param annotation_id: String, the id of the annotation :return: Annotation: an instance of TM1py.Annoation """ request = "/api/v1/Annotations('{}')?$expand=DimensionalContext($select=Name)".format(annotation_id) annotation_as_json = self._rest.GET(request=request) return Annotation.from_json(annotation_as_json) def update(self, annotation): """ update Annotation on TM1 Server :param annotation: instance of TM1py.Annotation :Notes: updateable attributes: commentValue """ request = "/api/v1/Annotations('{}')".format(annotation.id) return self._rest.PATCH(request=request, data=annotation.body) def delete(self, annotation_id): """ delete Annotation on TM1 Server :param annotation_id: string, the id of the annotation :return: string: the response """ request = "/api/v1/Annotations('{}')".format(annotation_id) return self._rest.DELETE(request=request)