def setUp(self): """ Instantiate subsets that will be available to all tests. """ self.static_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_static, elements=['USD', 'EUR', 'NZD', 'Dum\'my']) self.dynamic_subset = Subset( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + self.dimension_name + '] )} ) }') # subset constructed from only the mandatory arguments self.minimal_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_minimal) # a static subset constructed with optional arguments self.complete_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_complete, hierarchy_name=self.hierarchy_name, alias=self.subset_name_alias, elements=["a", "b", "c"]) # an instance of the AnonymoustSubset subclass self.anon_subset = AnonymousSubset(dimension_name=self.dimension_name, hierarchy_name=self.hierarchy_name, elements=["x", "y", "z"])
def setup_class(cls): cls.tm1 = TM1Service(**test_config) # Do random stuff cls.private = bool(random.getrandbits(1)) # Define Names cls.prefix = 'TM1py_unittest_dimension_' cls.dimension_name = cls.prefix + str(uuid.uuid4()) cls.subset_name_static = cls.prefix + str(uuid.uuid4()) cls.subset_name_dynamic = cls.prefix + str(uuid.uuid4()) # Instantiate Subsets cls.static_subset = Subset(dimension_name=cls.dimension_name, subset_name=cls.subset_name_static, elements=['USD', 'EUR', 'NZD']) cls.dynamic_subset = Subset( dimension_name=cls.dimension_name, subset_name=cls.subset_name_dynamic, expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + cls.dimension_name + '] )} ) }') elements = [ Element('USD', 'Numeric'), Element('EUR', 'Numeric'), Element('JPY', 'Numeric'), Element('CNY', 'Numeric'), Element('GBP', 'Numeric'), Element('NZD', 'Numeric') ] element_attributes = [ElementAttribute('Currency Name', 'String')] h = Hierarchy(cls.dimension_name, cls.dimension_name, elements, element_attributes) d = Dimension(cls.dimension_name, hierarchies=[h]) cls.tm1.dimensions.create(d)
def setUp(self): # Instantiate Subsets self.static_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_static, elements=['USD', 'EUR', 'NZD', 'Dum\'my']) self.dynamic_subset = Subset( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + self.dimension_name + '] )} ) }') elements = [ Element('USD', 'Numeric'), Element('EUR', 'Numeric'), Element('JPY', 'Numeric'), Element('CNY', 'Numeric'), Element('GBP', 'Numeric'), Element('NZD', 'Numeric'), Element('Dum\'my', 'Numeric') ] element_attributes = [ElementAttribute('Currency Name', 'String')] h = Hierarchy(self.dimension_name, self.dimension_name, elements, element_attributes) d = Dimension(self.dimension_name, hierarchies=[h]) self.tm1.dimensions.create(d) for private in (True, False): self.tm1.dimensions.subsets.create(subset=self.static_subset, private=private) self.tm1.dimensions.subsets.create(subset=self.dynamic_subset, private=private)
def test_create_and_delete_subset(self): for private in (True, False): static_subset = Subset(dimension_name=self.dimension_name, subset_name="subset1", elements=['USD', 'EUR', 'NZD', 'Dum\'my']) dynamic_subset = Subset( dimension_name=self.dimension_name, subset_name="subset2", expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + self.dimension_name + '] )} ) }') response = self.tm1.dimensions.subsets.create(subset=static_subset, private=private) self.assertTrue(response.ok) response = self.tm1.dimensions.hierarchies.subsets.delete( dimension_name=self.dimension_name, subset_name=static_subset.name, private=private) self.assertTrue(response.ok) response = self.tm1.dimensions.subsets.create( subset=dynamic_subset, private=private) self.assertTrue(response.ok) response = self.tm1.dimensions.hierarchies.subsets.delete( dimension_name=self.dimension_name, subset_name=dynamic_subset.name, private=private) self.assertTrue(response.ok)
def setUp(self): for private in (True, False): # create instance of native View native_view = NativeView( cube_name=CUBE_NAME, view_name=self.native_view_name) # Set up native view - put subsets on Rows, Columns and Titles subset = Subset( dimension_name=DIMENSION_NAMES[0], hierarchy_name=DIMENSION_NAMES[0], subset_name=SUBSET_NAME, expression='{{[{}].Members}}'.format(DIMENSION_NAMES[0])) self.tm1.dimensions.subsets.create(subset, private=False) native_view.add_row( dimension_name=DIMENSION_NAMES[0], subset=subset) subset = AnonymousSubset( dimension_name=DIMENSION_NAMES[1], hierarchy_name=DIMENSION_NAMES[1], elements=['element1', 'element123', 'element432']) native_view.add_title( dimension_name=DIMENSION_NAMES[1], subset=subset, selection='element123') elements = ['Element{}'.format(str(i)) for i in range(1, 201)] subset = Subset( dimension_name=DIMENSION_NAMES[2], hierarchy_name=DIMENSION_NAMES[2], subset_name=SUBSET_NAME, elements=elements) self.tm1.dimensions.subsets.create(subset, private=False) native_view.add_column( dimension_name=DIMENSION_NAMES[2], subset=subset) # Suppress Null Values native_view.suppress_empty_cells = True # create native view on Server self.tm1.cubes.views.create( view=native_view, private=private) # create instance of MDXView nv_view = self.tm1.cubes.views.get_native_view( cube_name=CUBE_NAME, view_name=self.native_view_name, private=private) mdx = nv_view.MDX mdx_view = MDXView( cube_name=CUBE_NAME, view_name=self.mdx_view_name, MDX=mdx) # create mdx view on Server self.tm1.cubes.views.create( view=mdx_view, private=private)
def test1_create_view(self): # create instance of native View native_view = NativeView(cube_name=cube_name, view_name=self.native_view_name) # Set up native view - put subsets on Rows, Columns and Titles subset = Subset(dimension_name=dimension_names[0], hierarchy_name=dimension_names[0], subset_name=str(uuid.uuid4()), expression='{{[{}].Members}}'.format( dimension_names[0])) self.tm1.dimensions.subsets.create(subset, private=False) native_view.add_row(dimension_name=dimension_names[0], subset=subset) subset = AnonymousSubset( dimension_name=dimension_names[1], hierarchy_name=dimension_names[1], elements=['element1', 'element123', 'element432']) native_view.add_title(dimension_name=dimension_names[1], subset=subset, selection='element123') elements = ['Element{}'.format(str(i)) for i in range(1, 201)] subset = Subset(dimension_name=dimension_names[2], hierarchy_name=dimension_names[2], subset_name=str(uuid.uuid4()), elements=elements) self.tm1.dimensions.subsets.create(subset, private=False) native_view.add_column(dimension_name=dimension_names[2], subset=subset) # Suppress Null Values native_view.suppress_empty_cells = True # create native view on Server self.tm1.cubes.views.create(view=native_view, private=self.random_boolean) # create instance of MDXView nv_view = self.tm1.cubes.views.get_native_view( cube_name=cube_name, view_name=self.native_view_name, private=self.random_boolean) mdx = nv_view.MDX mdx_view = MDXView(cube_name=cube_name, view_name=self.mdx_view_name, MDX=mdx) # create mdx view on Server self.tm1.cubes.views.create(view=mdx_view, private=self.random_boolean)
def setUpClass(cls): """ Establishes a connection to TM1 and creates TM! objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get(random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [element for element in cls.random_dimension_all_elements][0:2] # Subset process cls.subset_name = cls.prefix + '_subset_' + cls.some_name cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.update_or_create(cls.subset, False) cls.p_subset = Process(name=cls.prefix + '_subset_' + cls.some_name, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';") with open(Path(__file__).parent.joinpath('resources', 'Bedrock.Server.Wait.json'), 'r') as file: cls.p_bedrock_server_wait = Process.from_json(file.read())
def setUpClass(cls): cls.tm1 = TM1Service(**config['tm1srv01']) cls.random_string = str(uuid.uuid4()) cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get(random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [element for element in cls.random_dimension_all_elements][0:2] # None process cls.p_none = Process(name=process_prefix + '_none_' + cls.random_string, datasource_type='None') # ACII process cls.p_ascii = Process(name=process_prefix + '_ascii_' + cls.random_string, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # Variables cls.p_ascii.add_variable('v_1', 'Numeric') cls.p_ascii.add_variable('v_2', 'Numeric') cls.p_ascii.add_variable('v_3', 'Numeric') cls.p_ascii.add_variable('v_4', 'Numeric') # Parameters cls.p_ascii.add_parameter('p_Year', 'year?', '2016') cls.p_ascii.add_parameter('p_Number', 'number?', 2) # View process cls.p_view = Process(name=process_prefix + '_view_' + cls.random_string, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') # ODBC process cls.p_odbc = Process(name=process_prefix + '_odbc_' + cls.random_string, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') # Subset process cls.subset_name = process_prefix + '_subset_' + cls.random_string cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.create(cls.subset, False) cls.p_subset = Process(name=process_prefix + '_subset_' + cls.random_string, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';")
def test_delete_elements_from_static_subset_private(self): private = True static_subset = Subset(dimension_name=self.dimension_name, subset_name="subset1", elements=['USD', 'EUR', 'NZD', 'Dum\'my']) self.tm1.dimensions.subsets.create(subset=static_subset, private=private) subset = self.tm1.dimensions.subsets.get( dimension_name=static_subset.dimension_name, hierarchy_name=static_subset.hierarchy_name, subset_name=static_subset.name, private=private) self.assertEqual(len(subset.elements), 4) self.tm1.dimensions.subsets.delete_elements_from_static_subset( dimension_name=static_subset.dimension_name, hierarchy_name=static_subset.hierarchy_name, subset_name=static_subset.name, private=private) subset = self.tm1.dimensions.subsets.get( dimension_name=static_subset.dimension_name, hierarchy_name=static_subset.hierarchy_name, subset_name=static_subset.name, private=private) self.assertEqual(len(subset.elements), 0)
def test_create_subset_with_url_unfriendly_characters_in_name(self): subset = Subset(subset_name=self.unfriendly_subset_name, dimension_name=self.dimension_name, hierarchy_name=self.dimension_name, elements=[]) self.tm1.subsets.create(subset=subset, private=False) subset = self.tm1.subsets.get(dimension_name=self.dimension_name, subset_name=self.unfriendly_subset_name) self.assertEqual(self.unfriendly_subset_name, subset.name) self.assertEqual([], subset.elements)
def test_create_subset_with_url_unfriendly_characters_in_elements_dynamic( self): expression = "{[" + self.unfriendly_dimension_name + "].[" + self.unfriendly_element_name + "]}" subset = Subset(subset_name=self.unfriendly_subset_name, dimension_name=self.unfriendly_dimension_name, hierarchy_name=self.unfriendly_dimension_name, expression=expression) self.tm1.subsets.create(subset=subset, private=False) subset = self.tm1.subsets.get( dimension_name=self.unfriendly_dimension_name, subset_name=self.unfriendly_subset_name) self.assertEqual(self.unfriendly_subset_name, subset.name) self.assertEqual(expression, subset.expression)
def get(self, dimension_name, subset_name, private=True): """ get a subset from the TM1 Server :param dimension_name: string, name of the dimension :param subset_name: string, name of the subset :param private: Boolean :return: instance of TM1py.Subset """ subsets = "PrivateSubsets" if private else "Subsets" request = '/api/v1/Dimensions(\'{}\')/Hierarchies(\'{}\')/{}(\'{}\')?$expand=' \ 'Hierarchy($select=Dimension),' \ 'Elements($select=Name)&$select=*,Alias'.format(dimension_name, dimension_name, subsets, subset_name) response = self._rest.GET(request=request) return Subset.from_json(response)
def test_create_and_delete_subset_static_private(self): private = True static_subset = Subset(dimension_name=self.dimension_name, subset_name="subset1", elements=['USD', 'EUR', 'NZD', 'Dum\'my']) response = self.tm1.dimensions.subsets.create(subset=static_subset, private=private) self.assertTrue(response.ok) response = self.tm1.dimensions.hierarchies.subsets.delete( dimension_name=self.dimension_name, subset_name=static_subset.name, private=private) self.assertTrue(response.ok)
def test_create_and_delete_subset_dynamic_private(self): private = True dynamic_subset = Subset(dimension_name=self.dimension_name, subset_name="subset2", expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + self.dimension_name + '] )} ) }') response = self.tm1.dimensions.subsets.create(subset=dynamic_subset, private=private) self.assertTrue(response.ok) response = self.tm1.dimensions.hierarchies.subsets.delete( dimension_name=self.dimension_name, subset_name=dynamic_subset.name, private=private) self.assertTrue(response.ok)
def test1_create_hierarchy(self): d = Dimension(self.dimension_name) h = Hierarchy(self.dimension_name, self.dimension_name) h.add_element('Total Years', 'Consolidated') h.add_element('No Year', 'Numeric') h.add_element('1989', 'Numeric') h.add_element_attribute('Previous Year', 'String') h.add_element_attribute('Next Year', 'String') h.add_edge('Total Years', '1989', 2) d.add_hierarchy(h) self.tm1.dimensions.create(d) time.sleep(1) s = Subset(self.subset_name, self.dimension_name, self.dimension_name, expression="{{[{}].Members}}".format(self.dimension_name)) self.tm1.dimensions.subsets.create(s, False)
def get(self, subset_name: str, dimension_name: str, hierarchy_name: str = None, private: bool = False, **kwargs) -> Subset: """ get a subset from the TM1 Server :param subset_name: string, name of the subset :param dimension_name: string, name of the dimension :param hierarchy_name: string, name of the hierarchy :param private: Boolean :return: instance of TM1py.Subset """ if not hierarchy_name: hierarchy_name = dimension_name subsets = "PrivateSubsets" if private else "Subsets" url = format_url( "/api/v1/Dimensions('{}')/Hierarchies('{}')/{}('{}')?$expand=Hierarchy($select=Dimension,Name)," "Elements($select=Name)&$select=*,Alias", dimension_name, hierarchy_name, subsets, subset_name) response = self._rest.GET(url=url, **kwargs) return Subset.from_dict(response.json())
def build_date_dimension(tm1, dimension_name, first_date, last_date, overwrite): date_span = last_date - first_date dates = [ str(first_date + timedelta(day)) for day in range(date_span.days + 1) ] # Build Leaves leaves = [Element(name=date, element_type='Numeric') for date in dates] # Build Consolidations years = [str(year) for year in range(first_date.year, last_date.year + 1)] consolidations = [ Element(name=year, element_type='Consolidated') for year in years ] for year in years: for month in range(1, 13): year_month = year + "-" + str(month).zfill(2) consolidations.append( Element(name=year_month, element_type="Consolidated")) # Build Elements elements = leaves + consolidations # Build Edges edges = CaseAndSpaceInsensitiveTuplesDict() for year in years: for month in range(1, 13): year_month = year + "-" + str(month).zfill(2) edges[(year, year_month)] = 1 for date in filter(lambda d: d[0:4] == year, dates): year_month = date[0:7] edges[(year_month, date)] = 1 # Build Attribute attributes = [ ElementAttribute('Alias', 'Alias'), ElementAttribute('Year', 'String'), ElementAttribute('Month', 'String'), ElementAttribute('Day', 'String'), ElementAttribute('Weekday', 'String') ] # write Aliases attribute_values = {} for date in dates: # Year, Month, Day Attributes attribute_values[(date, 'Year')] = date.split('-')[0] attribute_values[(date, 'Month')] = date.split('-')[1] attribute_values[(date, 'Day')] = date.split('-')[2] attribute_values[( date, 'Weekday')] = dateutil.parser.parse(date).weekday() + 1 # US Notation as Alias year, month, day = [str(int(ymd)) for ymd in date.split('-')] attribute_values[(date, 'Alias')] = month + "/" + day + "/" + year # Build Hierarchy, Dimension hier = Hierarchy(name=dimension_name, dimension_name=dimension_name, elements=elements, edges=edges, element_attributes=attributes) dim = Dimension(name=dimension_name, hierarchies=[hier]) # Interaction with TM1 exists = tm1.dimensions.exists(dimension_name) if not exists: tm1.dimensions.create(dim) elif exists and overwrite: tm1.dimensions.update(dim) if not exists or overwrite: tm1.cubes.cells.write_values(cube_name="}ElementAttributes_" + dimension_name, cellset_as_dict=attribute_values) # Year Subsets for year in years: expr = "{ FILTER ( {TM1SubsetAll([Date])}, [Date].[Year] = '" + year + "' ) }" subset = Subset(year, dimension_name=dimension_name, hierarchy_name=dimension_name, expression=expr) if not tm1.dimensions.hierarchies.subsets.exists( year, dimension_name, dimension_name, private=False): tm1.dimensions.hierarchies.subsets.create(subset, private=False) else: tm1.dimensions.hierarchies.subsets.update(subset, private=False)
import configparser config = configparser.ConfigParser() config.read('..\config.ini') from TM1py.Objects import Subset from TM1py.Services import TM1Service dimension_name = "Region" subset_name = "TM1py Subset" elements = ['1', '2', '3'] with TM1Service(**config['tm1srv01']) as tm1: # create subset s = Subset(dimension_name=dimension_name, subset_name=subset_name, alias='', elements=elements) tm1.dimensions.subsets.create(subset=s, private=True) # get it and print out the elements s = tm1.dimensions.subsets.get(dimension_name=dimension_name, subset_name=subset_name, private=True) print(s.elements) # delete it tm1.dimensions.subsets.delete(dimension_name=dimension_name, subset_name=subset_name, private=True)
class TestProcessMethods(unittest.TestCase): tm1 = TM1Service(address=address, port=port, user=user, password=pwd, ssl=ssl) random_string = str(uuid.uuid4()) # None process p_none = Process(name=process_prefix + '_none_' + random_string, datasource_type='None') # ACII process p_ascii = Process( name=process_prefix + '_ascii_' + random_string, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # Variables p_ascii.add_variable('v_1', 'Numeric') p_ascii.add_variable('v_2', 'Numeric') p_ascii.add_variable('v_3', 'Numeric') p_ascii.add_variable('v_4', 'Numeric') # Parameters p_ascii.add_parameter('p_Year', 'year?', '2016') # View process p_view = Process(name=process_prefix + '_view_' + random_string, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') # ODBC process p_odbc = Process(name=process_prefix + '_odbc_' + random_string, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') # Subset process subset_name = process_prefix + '_subset_' + random_string subset = Subset(dimension_name='plan_business_unit', subset_name=subset_name, elements=['10110', '10120', '10200', '10210']) tm1.subsets.create(subset, False) p_subset = Process( name=process_prefix + '_subset_' + random_string, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=subset.dimension_name, datasource_subset=subset.name, metadata_procedure="sTest = 'abc';") # Create Process def test1_create_process(self): self.tm1.processes.create(self.p_none) self.tm1.processes.create(self.p_ascii) self.tm1.processes.create(self.p_view) self.tm1.processes.create(self.p_odbc) self.tm1.processes.create(self.p_subset) # Get Process def test2_get_process(self): p1 = self.tm1.processes.get(self.p_ascii.name) self.assertEqual(p1.body, self.p_ascii.body) p2 = self.tm1.processes.get(self.p_none.name) self.assertEqual(p2.body, self.p_none.body) p3 = self.tm1.processes.get(self.p_view.name) self.assertEqual(p3.body, self.p_view.body) p4 = self.tm1.processes.get(self.p_odbc.name) p4.datasource_password = None self.p_odbc.datasource_password = None self.assertEqual(p4.body, self.p_odbc.body) p5 = self.tm1.processes.get(self.p_subset.name) self.assertEqual(p5.body, self.p_subset.body) # Update process def test3_update_process(self): # get p = self.tm1.processes.get(self.p_ascii.name) # modify p.data_procedure = "SaveDataAll;" # update on Server self.tm1.processes.update(p) # get again p_ascii_updated = self.tm1.processes.get(p.name) # assert self.assertNotEqual(p_ascii_updated.data_procedure, self.p_ascii.data_procedure) # Delete process def test4_delete_process(self): self.tm1.processes.delete(self.p_none.name) self.tm1.processes.delete(self.p_ascii.name) self.tm1.processes.delete(self.p_view.name) self.tm1.processes.delete(self.p_odbc.name) self.tm1.processes.delete(self.p_subset.name) self.tm1.subsets.delete(self.subset.dimension_name, self.subset_name, False) def test5_logout(self): self.tm1.logout()
def create_subset(cls): s = Subset(cls.subset_name, cls.dimension_name, cls.dimension_name, expression="{{[{}].Members}}".format(cls.dimension_name)) cls.tm1.dimensions.subsets.create(s, False)
""" import configparser import uuid from TM1py.Objects import Subset from TM1py.Services import TM1Service config = configparser.ConfigParser() config.read('..\config.ini') with TM1Service(**config['tm1srv01']) as tm1: # get a random string that we can use a subset name subset_name = str(uuid.uuid4()) # create subset s = Subset(dimension_name='Plan_Department', subset_name=subset_name, alias='', elements=['200', '405', '410']) tm1.dimensions.subsets.create(s, True) # get it and print out the elements s = tm1.dimensions.subsets.get(dimension_name='Plan_Department', subset_name=subset_name, private=True) print(s.elements) # update it s.add_elements(['105', '115']) tm1.dimensions.subsets.update(s, True) # get it and print out the elements s = tm1.dimensions.subsets.get(dimension_name='Plan_Department', subset_name=subset_name, private=True) print(s.elements) # delete it
def test_from_json(self): s = Subset.from_json(self.subset_json) self.assertEqual(s.name, "json_subset") self.assertEqual(s.elements, ["xoy", "o", "xxx"])
def create_subset(cls): s = Subset(SUBSET_NAME, DIMENSION_NAME, DIMENSION_NAME, expression="{{[{}].Members}}".format(DIMENSION_NAME)) cls.tm1.dimensions.subsets.create(s, False)
def main(tm1): version_dimension_name = 'Version' version_dimension_elements = ('Actual', 'Detailed Forecast', 'Prophet Forecast') build_simple_dimension(tm1, version_dimension_name, version_dimension_elements, overwrite=True) # Create Default Subset subset = Subset('Default', version_dimension_name, version_dimension_name, elements=version_dimension_elements) if not tm1.dimensions.hierarchies.subsets.exists( subset_name=subset.name, dimension_name=subset.dimension_name, hierarchy_name=subset.dimension_name, private=False): tm1.dimensions.hierarchies.subsets.create(subset, private=False) else: tm1.dimensions.hierarchies.subsets.update(subset, private=False) measure_dimension_name = 'Bike Shares Measure' measure_dimension_elements = ('Count', 'Count Lower', 'Count Upper', 'Seconds', 'Minutes', 'Hours', 'Days') build_simple_dimension(tm1, measure_dimension_name, measure_dimension_elements, overwrite=True) # Create Default Subset subset = Subset('Default', measure_dimension_name, measure_dimension_name, elements=measure_dimension_elements) if not tm1.dimensions.hierarchies.subsets.exists( subset_name=subset.name, dimension_name=subset.dimension_name, hierarchy_name=subset.dimension_name, private=False): tm1.dimensions.hierarchies.subsets.create(subset, private=False) else: tm1.dimensions.hierarchies.subsets.update(subset, private=False) city_dimension_name = 'City' city_dimension_elements = ('Chicago', 'NYC', 'Washington') build_simple_dimension(tm1, city_dimension_name, city_dimension_elements, overwrite=True) # Create Default Subset subset = Subset('Default', city_dimension_name, city_dimension_name, elements=city_dimension_elements) if not tm1.dimensions.hierarchies.subsets.exists( subset_name=subset.name, dimension_name=subset.dimension_name, hierarchy_name=subset.dimension_name, private=False): tm1.dimensions.hierarchies.subsets.create(subset, private=False) else: tm1.dimensions.hierarchies.subsets.update(subset, private=False) date_dimension_name = 'Date' first_date = date(2010, 1, 1) last_date = date(2025, 12, 31) build_date_dimension(tm1, date_dimension_name, first_date, last_date, overwrite=True) # Build Bike Shares Cube cube_name = 'Bike Shares' dimensions = (version_dimension_name, date_dimension_name, city_dimension_name, measure_dimension_name) rules = "SKIPCHECK; \r\n" \ "['Bike Shares Measure':'Minutes'] = N: ['Bike Shares Measure':'Seconds'] / 60; \r\n" \ "['Bike Shares Measure':'Hours'] = N: ['Bike Shares Measure':'Seconds'] / (60 * 60); \r\n" \ "['Bike Shares Measure':'Days'] = N: ['Bike Shares Measure':'Seconds'] / (60 * 60 * 24); \r\n" \ "FEEDERS; \r\n" \ "['Bike Shares Measure':'Seconds'] =>['Bike Shares Measure':'Minutes']; \r\n" \ "['Bike Shares Measure':'Seconds'] =>['Bike Shares Measure':'Hours']; \r\n" \ "['Bike Shares Measure':'Seconds'] => ['Bike Shares Measure':'Days']; \r\n" build_cube(tm1, cube_name, dimensions, rules=rules, overwrite=True) # Build Weather Cube weather_measure_element_names = ("TMAX", "TMIN", 'TAVG') weather_measure_dimension = 'Weather Data Measure' build_simple_dimension(tm1, dimension_name=weather_measure_dimension, dimension_elements=weather_measure_element_names, overwrite=True) weather_cube_name = 'Weather Data' dimensions = (version_dimension_name, date_dimension_name, city_dimension_name, weather_measure_dimension) rules = "[] = C: IF ( DTYPE('Date', !Date) @= 'N' , \r\n" \ "STET, \r\n" \ "CONTINUE ); \r\n" \ "['Weather Data Measure':'TMIN'] = C: ConsolidatedMin(1, 'Weather Data', !Version, !Date, !City, !Weather Data Measure); \r\n" \ "['Weather Data Measure':'TAVG'] = C: ConsolidatedAvg(1, 'Weather Data', !Version, !Date, !City, !Weather Data Measure); \r\n" \ "['Weather Data Measure':'TMAX'] = C: ConsolidatedMax(1, 'Weather Data', !Version, !Date, !City, !Weather Data Measure);" build_cube(tm1, weather_cube_name, dimensions, rules=rules, overwrite=True) # Build Holiday Measure Dimension holidays_measure_dimension_element_names = ("Public Holiday", ) holidays_measure_dimension_name = 'Public Holidays Measure' build_simple_dimension( tm1, dimension_name=holidays_measure_dimension_name, dimension_elements=holidays_measure_dimension_element_names, overwrite=True) # Build Holiday Cube holidays_cube_name = "Public Holidays" holidays_cube_dimensions = (date_dimension_name, city_dimension_name, holidays_measure_dimension_name) build_cube(tm1, holidays_cube_name, holidays_cube_dimensions, rules=None, overwrite=True) write_public_holidays_to_cube(tm1, holidays_cube_name) # build views build_views(tm1, overwrite=True) # Load Historic Weather station_city_mapping = { 'GHCND:USW00014732': 'NYC', 'GHCND:USW00094846': 'Chicago', 'GHCND:USW00093721': 'Washington' } load_weather_data(tm1, station_city_mapping, weather_cube_name) # load raw Bike Shares data load_data_washington_dc(tm1, cube_name) load_data_chicago(tm1, cube_name) load_data_nyc(tm1, cube_name)
def setUpClass(cls): """ Establishes a connection to TM1 and creates TM! objects to use across all tests """ # Connection to TM1 cls.config = configparser.ConfigParser() cls.config.read(Path(__file__).parent.joinpath('config.ini')) cls.tm1 = TM1Service(**cls.config['tm1srv01']) cls.some_name = "some_name" cls.all_dimension_names = cls.tm1.dimensions.get_all_names() cls.random_dimension = cls.tm1.dimensions.get( random.choice(cls.all_dimension_names)) cls.random_dimension_all_elements = cls.random_dimension.default_hierarchy.elements cls.random_dimension_elements = [ element for element in cls.random_dimension_all_elements ][0:2] # None process cls.p_none = Process(name=PROCESS_PREFIX + '_none_' + cls.some_name, datasource_type='None') # ACII process cls.p_ascii = Process( name=PROCESS_PREFIX + '_ascii_' + cls.some_name, datasource_type='ASCII', datasource_ascii_delimiter_type='Character', datasource_ascii_delimiter_char=',', datasource_ascii_header_records=2, datasource_ascii_quote_character='^', datasource_ascii_thousand_separator='~', prolog_procedure="sTestProlog = 'test prolog procedure'", metadata_procedure="sTestMeta = 'test metadata procedure'", data_procedure="sTestData = 'test data procedure'", epilog_procedure="sTestEpilog = 'test epilog procedure'", datasource_data_source_name_for_server=r'C:\Data\file.csv', datasource_data_source_name_for_client=r'C:\Data\file.csv') # Variables cls.p_ascii.add_variable('v_1', 'Numeric') cls.p_ascii.add_variable('v_2', 'Numeric') cls.p_ascii.add_variable('v_3', 'Numeric') cls.p_ascii.add_variable('v_4', 'Numeric') # Parameters cls.p_ascii.add_parameter('p_Year', 'year?', '2016') cls.p_ascii.add_parameter('p_Number', 'number?', 2) # View process cls.p_view = Process( name=PROCESS_PREFIX + '_view_' + cls.some_name, datasource_type='TM1CubeView', datasource_view='view1', datasource_data_source_name_for_client='Plan_BudgetPlan', datasource_data_source_name_for_server='Plan_BudgetPlan') # ODBC process cls.p_odbc = Process(name=PROCESS_PREFIX + '_odbc_' + cls.some_name, datasource_type='ODBC', datasource_password='******', datasource_user_name='user') # Subset process cls.subset_name = PROCESS_PREFIX + '_subset_' + cls.some_name cls.subset = Subset(dimension_name=cls.random_dimension.name, subset_name=cls.subset_name, elements=cls.random_dimension_elements) cls.tm1.dimensions.subsets.create(cls.subset, False) cls.p_subset = Process( name=PROCESS_PREFIX + '_subset_' + cls.some_name, datasource_type='TM1DimensionSubset', datasource_data_source_name_for_server=cls.subset.dimension_name, datasource_subset=cls.subset.name, metadata_procedure="sTest = 'abc';") with open( Path(__file__).parent.joinpath('resources', 'Bedrock.Server.Wait.json'), 'r') as file: cls.p_bedrock_server_wait = Process.from_json(file.read())
def test_from_dict(self): s = Subset.from_dict(self.subset_dict) self.assertEqual(s.name, "dict_subset") self.assertEqual(s.elements, ["x", "y", "z"])
class TestSubset(unittest.TestCase): @classmethod def setUpClass(cls): """ Create any class scoped fixtures here. """ cls.dimension_name = PREFIX + "dimension" cls.hierarchy_name = PREFIX + "hierarchy" cls.subset_name_static = PREFIX + "static_subset" cls.subset_name_dynamic = PREFIX + "dynamic_subset" cls.subset_name_minimal = PREFIX + "minimal_subset" cls.subset_name_complete = PREFIX + "complete_subset" cls.subset_name_alias = PREFIX + "alias_subset" cls.subset_name_anon = PREFIX + "anon_subset" cls.element_name = PREFIX + "element" cls.subset_dict = { "Name": "dict_subset", "UniqueName": f"[{cls.dimension_name}]", "Hierarchy": { "Name": f"{cls.hierarchy_name}" }, "Alias": "dict_subset" + "_alias", "Elements": [{ "Name": "x" }, { "Name": "y" }, { "Name": "z" }], "Expression": "" } cls.subset_json = ''' { "Name": "json_subset", "UniqueName" : "json_subset", "Hierarchy": { "Name": "json_subset" }, "Alias": "json_subset_alias", "Elements" : [ { "Name" : "xoy" }, { "Name": "o" }, { "Name": "xxx" } ], "Expression" : "" } ''' def setUp(self): """ Instantiate subsets that will be available to all tests. """ self.static_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_static, elements=['USD', 'EUR', 'NZD', 'Dum\'my']) self.dynamic_subset = Subset( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + self.dimension_name + '] )} ) }') # subset constructed from only the mandatory arguments self.minimal_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_minimal) # a static subset constructed with optional arguments self.complete_subset = Subset(dimension_name=self.dimension_name, subset_name=self.subset_name_complete, hierarchy_name=self.hierarchy_name, alias=self.subset_name_alias, elements=["a", "b", "c"]) # an instance of the AnonymoustSubset subclass self.anon_subset = AnonymousSubset(dimension_name=self.dimension_name, hierarchy_name=self.hierarchy_name, elements=["x", "y", "z"]) def tearDown(self): """ Remove any artifacts created. """ # nothing required here, all objects will be reset by setUp pass def test_is_dynamic(self): self.assertTrue(self.dynamic_subset.is_dynamic) self.assertFalse(self.static_subset.is_dynamic) self.assertFalse(self.minimal_subset.is_dynamic) self.assertFalse(self.complete_subset.is_dynamic) self.assertFalse(self.anon_subset.is_dynamic) def test_is_static(self): self.assertFalse(self.dynamic_subset.is_static) self.assertTrue(self.static_subset.is_static) self.assertTrue(self.minimal_subset.is_static) self.assertTrue(self.complete_subset.is_static) self.assertTrue(self.anon_subset.is_static) def test_from_json(self): s = Subset.from_json(self.subset_json) self.assertEqual(s.name, "json_subset") self.assertEqual(s.elements, ["xoy", "o", "xxx"]) def test_from_dict(self): s = Subset.from_dict(self.subset_dict) self.assertEqual(s.name, "dict_subset") self.assertEqual(s.elements, ["x", "y", "z"]) def test_add_elements(self): self.static_subset.add_elements(["AUD", "CHF"]) self.assertIn("AUD", self.static_subset.elements) self.assertIn("CHF", self.static_subset.elements) def test_anonymous_subset(self): self.assertEqual(self.anon_subset.name, "") def test_property_setters(self): self.minimal_subset.elements = ["1", "2", "3"] self.assertEqual(self.minimal_subset.elements, ["1", "2", "3"]) def test_property_getters(self): self.assertEqual(self.complete_subset.name, self.subset_name_complete) self.assertEqual(self.dynamic_subset.name, self.subset_name_dynamic) self.assertEqual(self.static_subset.dimension_name, self.dimension_name) self.assertEqual(self.minimal_subset.elements, []) self.assertIn("a", self.complete_subset.elements) def test_subset_equality(self): self.assertNotEqual(self.complete_subset, self.minimal_subset) self.assertNotEqual(self.complete_subset, self.anon_subset) self.assertNotEqual(self.complete_subset, self.static_subset) self.assertNotEqual(self.complete_subset, self.dynamic_subset) static_subset_copy = self.static_subset self.assertEqual(static_subset_copy, self.static_subset) @classmethod def tearDownClass(cls): """ Tear down anything as required """ # nothing to do here pass
- Delete it """ import uuid from TM1py.Objects import Subset from TM1py.Services import TM1Service with TM1Service(address='localhost', port=12354, user='******', password='******', ssl=True) as tm1: # get a random string that we can use a subset name subset_name = str(uuid.uuid4()) # create subset s = Subset(dimension_name='Plan_Department', subset_name=subset_name, alias='', elements=['200', '405', '410']) tm1.dimensions.subsets.create(s, True) # get it and print out the elements s = tm1.dimensions.subsets.get(dimension_name='Plan_Department', subset_name=subset_name, private=True) print(s.elements) # update it s.add_elements(['105', '115']) tm1.dimensions.subsets.update(s, True) # get it and print out the elements s = tm1.dimensions.subsets.get(dimension_name='Plan_Department', subset_name=subset_name, private=True) print(s.elements) # delete it
class TestSubsetMethods(unittest.TestCase): tm1 = TM1Service(address=address, port=port, user=user, password=pwd, ssl=ssl) # Do random stuff random_string = str(uuid.uuid4()) private = bool(random.getrandbits(1)) # Define Names dimension_name = 'TM1py_unittest_dimension_' + random_string subset_name_static = 'TM1py_unittest_static_subset_' + random_string subset_name_dynamic = 'TM1py_unittest_dynamic_subset_' + random_string # Instantiate Subsets static_subset = Subset(dimension_name=dimension_name, subset_name=subset_name_static, elements=['USD', 'EUR', 'NZD']) dynamic_subset = Subset(dimension_name=dimension_name, subset_name=subset_name_dynamic, expression='{ HIERARCHIZE( {TM1SUBSETALL( [' + dimension_name + '] )} ) }') # Check if Dimensions exists. If not create it @classmethod def setup_class(cls): elements = [ Element('USD', 'Numeric'), Element('EUR', 'Numeric'), Element('JPY', 'Numeric'), Element('CNY', 'Numeric'), Element('GBP', 'Numeric'), Element('NZD', 'Numeric') ] element_attributes = [ElementAttribute('Currency Name', 'String')] h = Hierarchy(cls.dimension_name, cls.dimension_name, elements, element_attributes) d = Dimension(cls.dimension_name, hierarchies=[h]) cls.tm1.dimensions.create(d) # 1. Create subset def test_1create_subset(self): self.tm1.subsets.create(self.static_subset, private=self.private) self.tm1.dimensions.hierarchies.subsets.create(self.dynamic_subset, private=self.private) # 2. Get subset def test_2get_subset(self): s = self.tm1.dimensions.hierarchies.subsets.get( dimension_name=self.dimension_name, subset_name=self.subset_name_static, private=self.private) self.assertEqual(self.static_subset.body, s.body) s = self.tm1.dimensions.hierarchies.subsets.get( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, private=self.private) self.assertEqual(self.dynamic_subset.body, s.body) # 3. Update subset def test_3update_subset(self): s = self.tm1.dimensions.hierarchies.subsets.get( dimension_name=self.dimension_name, subset_name=self.subset_name_static, private=self.private) s.add_elements(['NZD']) # Update it self.tm1.dimensions.hierarchies.subsets.update(s, private=self.private) # Get it again s = self.tm1.dimensions.hierarchies.subsets.get( dimension_name=self.dimension_name, subset_name=self.subset_name_static, private=self.private) # Test it ! self.assertEquals(len(s.elements), 4) # Get subset s = self.tm1.dimensions.hierarchies.subsets.get( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, private=self.private) s.expression = '{{ [{}].[EUR], [{}].[USD] }})'.format( self.dimension_name, self.dimension_name) # Update it self.tm1.dimensions.hierarchies.subsets.update(subset=s, private=self.private) # Get it again s = self.tm1.dimensions.hierarchies.subsets.get( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, private=self.private) # Test it ! self.assertEquals( s.expression, '{{ [{}].[EUR], [{}].[USD] }})'.format(self.dimension_name, self.dimension_name)) # 4. Delete subsets def test_4delete_subset(self): self.tm1.dimensions.hierarchies.subsets.delete( dimension_name=self.dimension_name, subset_name=self.subset_name_static, private=self.private) self.tm1.dimensions.hierarchies.subsets.delete( dimension_name=self.dimension_name, subset_name=self.subset_name_dynamic, private=self.private) @classmethod def teardown_class(cls): cls.tm1.dimensions.delete(cls.dimension_name) cls.tm1.logout()