Example #1
0
    def update(self, dimension: Dimension, **kwargs):
        """ Update an existing dimension

        :param dimension: instance of TM1py.Dimension
        :return: None
        """
        # delete hierarchies that have been removed from the dimension object
        hierarchies_to_be_removed = CaseAndSpaceInsensitiveSet(
            *self.hierarchies.get_all_names(dimension.name, **kwargs))
        for hierarchy in dimension.hierarchy_names:
            hierarchies_to_be_removed.discard(hierarchy)

        # update all Hierarchies except for the implicitly maintained 'Leaves' Hierarchy
        for hierarchy in dimension:
            if not case_and_space_insensitive_equals(hierarchy.name, "Leaves"):
                if self.hierarchies.exists(hierarchy.dimension_name,
                                           hierarchy.name, **kwargs):
                    self.hierarchies.update(hierarchy, **kwargs)
                else:
                    self.hierarchies.create(hierarchy, **kwargs)

        for hierarchy_name in hierarchies_to_be_removed:
            if not case_and_space_insensitive_equals(hierarchy_name, "Leaves"):
                self.hierarchies.delete(dimension_name=dimension.name,
                                        hierarchy_name=hierarchy_name,
                                        **kwargs)
Example #2
0
    def remove_hierarchy(self, hierarchy_name: str):
        if case_and_space_insensitive_equals(hierarchy_name, "leaves"):
            raise ValueError("'Leaves' hierarchy must not be removed from dimension")

        for num, hierarchy in enumerate(self._hierarchies):
            if case_and_space_insensitive_equals(hierarchy.name, hierarchy_name):
                del self._hierarchies[num]
                return
Example #3
0
    def update_default_member(self,
                              dimension_name,
                              hierarchy_name=None,
                              member_name=""):
        """ Update the default member of a hierarchy.
        Currently implemented through TI, since TM1 API does not supports default member updates yet.

        :param dimension_name:
        :param hierarchy_name:
        :param member_name:
        :return:
        """
        from TM1py import ProcessService, CellService
        if hierarchy_name and not case_and_space_insensitive_equals(
                dimension_name, hierarchy_name):
            dimension = "{}:{}".format(dimension_name, hierarchy_name)
        else:
            dimension = dimension_name
        cells = {(dimension, 'hierarchy0', 'defaultMember'): member_name}

        CellService(self._rest).write_values(
            cube_name="}HierarchyProperties",
            cellset_as_dict=cells,
            dimensions=('}Dimensions', '}Hierarchies', '}HierarchyProperties'))

        return ProcessService(self._rest).execute_ti_code(
            lines_prolog="RefreshMdxHierarchy('{}');".format(dimension_name))
Example #4
0
    def create(self, dimension: Dimension, **kwargs) -> Response:
        """ Create a dimension

        :param dimension: instance of TM1py.Dimension
        :return: response
        """
        # If Dimension exists. throw Exception
        if self.exists(dimension.name):
            raise RuntimeError("Dimension '{}' already exists".format(
                dimension.name))
        # If not all subsequent calls successful -> undo everything that has been done in this function
        try:
            # Create Dimension, Hierarchies, Elements, Edges.
            url = "/api/v1/Dimensions"
            response = self._rest.POST(url, dimension.body, **kwargs)
            # Create ElementAttributes
            for hierarchy in dimension:
                if not case_and_space_insensitive_equals(
                        hierarchy.name, "Leaves"):
                    self.hierarchies.update_element_attributes(
                        hierarchy, **kwargs)
        except TM1pyException as e:
            # undo everything if problem in step 1 or 2
            if self.exists(dimension.name, **kwargs):
                self.delete(dimension.name)
            raise e
        return response
Example #5
0
 def get_hierarchy(self, hierarchy_name):
     for hierarchy in self._hierarchies:
         if case_and_space_insensitive_equals(hierarchy.name,
                                              hierarchy_name):
             return hierarchy
     raise ValueError("Hierarchy: {} not found in dimension: {}".format(
         hierarchy_name, self.name))
Example #6
0
    def test_get_current_user(self):
        me = self.tm1.security.get_current_user()
        self.assertTrue(
            case_and_space_insensitive_equals(me.name,
                                              self.config['tm1srv01']['User']))

        user = self.tm1.security.get_user(self.config['tm1srv01']['User'])
        self.assertEqual(me, user)
Example #7
0
 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
Example #8
0
    def update(self, dimension: Dimension, **kwargs):
        """ Update an existing dimension

        :param dimension: instance of TM1py.Dimension
        :return: None
        """
        # delete hierarchies that have been removed from the dimension object
        hierarchies_to_be_removed = CaseAndSpaceInsensitiveSet(
            *self.hierarchies.get_all_names(dimension.name, **kwargs))
        for hierarchy in dimension.hierarchy_names:
            hierarchies_to_be_removed.discard(hierarchy)

        # update all Hierarchies except for the implicitly maintained 'Leaves' Hierarchy
        for hierarchy in dimension:
            if not case_and_space_insensitive_equals(hierarchy.name, "Leaves"):
                if self.hierarchies.exists(hierarchy.dimension_name,
                                           hierarchy.name, **kwargs):
                    self.hierarchies.update(hierarchy, **kwargs)
                else:
                    self.hierarchies.create(hierarchy, **kwargs)

        # Edge case: elements in leaves hierarchy that do not exist in other hierarchies
        if "Leaves" in dimension:
            existing_leaves = CaseAndSpaceInsensitiveSet(
                self.hierarchies.elements.get_leaf_element_names(
                    dimension.name, "Leaves"))

            leaves_to_create = list()
            for leaf in dimension.get_hierarchy("Leaves"):
                if leaf.name not in existing_leaves:
                    leaves_to_create.append(leaf)

            if leaves_to_create:
                self.hierarchies.elements.add_elements(
                    dimension_name=dimension.name,
                    hierarchy_name="Leaves",
                    elements=leaves_to_create)

        for hierarchy_name in hierarchies_to_be_removed:
            if not case_and_space_insensitive_equals(hierarchy_name, "Leaves"):
                self.hierarchies.delete(dimension_name=dimension.name,
                                        hierarchy_name=hierarchy_name,
                                        **kwargs)
Example #9
0
 def _construct_body(self, include_leaves_hierarchy=False) -> Dict:
     body_as_dict = collections.OrderedDict()
     body_as_dict["Name"] = self._name
     body_as_dict["UniqueName"] = self.unique_name
     body_as_dict["Attributes"] = self._attributes
     body_as_dict["Hierarchies"] = [
         hierarchy.body_as_dict for hierarchy in self.hierarchies
         if not case_and_space_insensitive_equals(hierarchy.name, "Leaves")
         or include_leaves_hierarchy
     ]
     return body_as_dict
Example #10
0
    def get_ancestors(self,
                      element_name: str,
                      recursive: bool = False) -> Set[Element]:
        ancestors = set()

        for (parent, component) in self._edges:
            if not case_and_space_insensitive_equals(component, element_name):
                continue

            ancestor: Element = self.elements[parent]
            ancestors.add(ancestor)

            if recursive:
                ancestors = ancestors.union(
                    self.get_ancestors(ancestor.name, True))
        return ancestors
Example #11
0
    def get_descendant_edges(self,
                             element_name: str,
                             recursive: bool = False) -> Dict:
        descendant_edges = dict()

        for (parent, component), weight in self._edges.items():
            if not case_and_space_insensitive_equals(parent, element_name):
                continue

            descendant_edges[parent, component] = weight
            descendant: Element = self.elements[component]

            if recursive and descendant.element_type == Element.Types.CONSOLIDATED:
                descendant_edges.update(
                    self.get_descendant_edges(descendant.name, True))

        return descendant_edges
Example #12
0
    def get_descendants(self,
                        element_name: str,
                        recursive: bool = False,
                        leaves_only=False) -> Set[Element]:
        descendants = set()

        for (parent, component) in self._edges:
            if not case_and_space_insensitive_equals(parent, element_name):
                continue

            descendant: Element = self.elements[component]
            if not leaves_only:
                descendants.add(descendant)
            else:
                if descendant.element_type == Element.Types.NUMERIC:
                    descendants.add(descendant)

            if recursive and descendant.element_type == Element.Types.CONSOLIDATED:
                descendants = descendants.union(
                    self.get_descendants(descendant.name, True))
        return descendants
Example #13
0
 def remove_element_attribute(self, name: str):
     self._element_attributes = [
         element_attribute for element_attribute in self.element_attributes
         if
         not case_and_space_insensitive_equals(element_attribute.name, name)
     ]
Example #14
0
 def contains_hierarchy(self, hierarchy_name):
     for hierarchy in self._hierarchies:
         if case_and_space_insensitive_equals(hierarchy.name,
                                              hierarchy_name):
             return True
     return False