cubewise-code / tm1py-samples

Do more with TM1 with these ready to use TM1py samples.
https://github.com/cubewise-code/TM1py
MIT License
59 stars 44 forks source link

CellSet Error Writing to Another Instance #37

Closed ToddGaluska closed 5 years ago

ToddGaluska commented 5 years ago

I have two identical models and trying to replicate changes by monitoring the transaction log delta. Any ideas why I am receiving the error below. I am on PA 2.0, Python 18.1

import configparser config = configparser.ConfigParser() config.read(r'C:\Users\tg\config.ini') ['C:\Users\tga\config.ini'] import time from TM1py import TM1Service cube_source = "Income Statement" cube_target = "Income Statement" with TM1Service(config['SmartCo IV']) as tm1_source: ... tm1_source.server.initialize_transaction_log_delta_requests("Cube eq '" + cube_source + "'") ... def job(): ... entries = tm1_source.server.execute_transaction_log_delta_request() ... if len(entries) > 0: ... cellset = dict() ... for entry in entries: ... cellset[tuple(entry["Tuple"])] = entry["NewValue"] ... print(cellset) ... with TM1Service(config['SmartCo V']) as tm1_target: ... tm1_target.cubes.cells.write_values(cube_target, cellset) ... while True: ... job() ... time.sleep(1) ... {('Plan', '2018-01', 'Massachusetts', 'Revenue', 'Amount'): 100000} Traceback (most recent call last): File "", line 13, in File "", line 11, in job File "C:\Users\tgaluska\AppData\Local\Programs\Python\Python37-32\lib\site-packages\TM1py\Services\CellService.py", line 126, in write_values return self._rest.POST(request=request, data=updates) File "C:\Users\tgaluska\AppData\Local\Programs\Python\Python37-32\lib\site-packages\TM1py\Services\RESTService.py", line 30, in wrapper self.verify_response(response=response) File "C:\Users\tgaluska\AppData\Local\Programs\Python\Python37-32\lib\site-packages\TM1py\Services\RESTService.py", line 214, in verify_response raise TM1pyException(response.text, status_code=response.status_code, reason=response.reason) TM1py.Exceptions.Exceptions.TM1pyException: Text: {"error":{"code":"278","message":"'Plan' can not be found in collection of type 'Element'."}} Status Code: 404 Reason: Not Found

MariusWirtz commented 5 years ago

Judging from the exception it looks like the element „Plan“ doesn’t exist in the dimension on the target instance.

Are you sure your dimensions are aligned between source and target instance ?

ToddGaluska commented 5 years ago

Thank you so much for the quick response. I have to say I love TM1PY and found a load of use cases so far. I should have included my assumption that element Plan was missing from the target cube. See attached screenshot of both SmartCo IV and SmarCo V TM1 models. As you can see from the view "Plan" existing in both cubes. If you have any other idea it would be greatly apprciated? planelementmissingerror

MariusWirtz commented 5 years ago

Hi @ecapitaladvisors,

Is the order (I mean the shown order, not the technical dimension order) of the dimensions the same in the source cube and the target cube?

If this is not it, perhaps you are not actually connection to to SmartCo V, but some other instance where the Planelement really does not exist. Can you please doublecheck the ports in the config.ini or run this:


import configparser

from TM1py.Services.TM1Service import TM1Service

config = configparser.ConfigParser()
config.read(r'config.ini')

with TM1Service(**config['SmartCo IV']) as tm1_source:
    print(tm1_source.server.get_server_name())

with TM1Service(**config['SmartCo V']) as tm1_source:
    print(tm1_source.server.get_server_name())
ToddGaluska commented 5 years ago

smartco iv dimensions smartco v dimensions

Marius,

Thanks for the reply. Shown Order is in attached screenshots. I ran the code below and you can see that both SmartCo VI and SmartCo V were returned.

import configparser from TM1py.Services.TM1Service import TM1Service config = configparser.ConfigParser() config.read(r'C:\Users\tg\config.ini') ['C:\Users\tg\config.ini'] with TM1Service(config['SmartCo IV']) as tm1_source: ... print(tm1_source.server.get_server_name()) ... SmartCo IV import configparser from TM1py.Services.TM1Service import TM1Service config = configparser.ConfigParser() config.read(r'C:\Users\tg\config.ini') ['C:\Users\tg\config.ini'] with TM1Service(config['SmartCo V']) as tm1_source: ... print(tm1_source.server.get_server_name()) ... SmartCo V

I also tried to manually create a cellset and change the values to see if the dimensions were in a different order than what I expected.

Tried these with the below code. cellset[('Plan','2018-01','Massachusetts','Revenue','Amount')] = 500000 cellset[('2018-01','Plan','Massachusetts','Revenue','Amount')] = 500000 cellset[('Massachusetts','2018-01','Plan','Revenue','Amount')] = 500000 cellset[('Revenue','2018-01','Massachusetts','Plan','Amount')] = 500000 cellset[('Amount','2018-01','Massachusetts','Revenue','Plan')] = 500000

All error messages returned with the first value not being an element in the dimension. Same error as before.

import configparser config = configparser.ConfigParser() config.read(r'C:\Users\tg\config.ini') import time from TM1py import TM1Service cube_target = "Income Statement" with TM1Service(**config['SmartCo V']) as tm1_target: cellset = {} cellset[('Plan','2018-01','Massachusetts','Revenue','Amount')] = 500000 tm1_target.cubes.cells.write_values(cube_target, cellset)

TM1py.Exceptions.Exceptions.TM1pyException: Text: {"error":{"code":"278","message":"'Plan' can not be found in collection of type 'Element'."}} Status Code: 404 Reason: Not Found

MariusWirtz commented 5 years ago

are you perhaps using a version of TM1 pre 10.2.2 FP7 ? There were some issues in the API before version 10.2.2 FP 7.

Please run this script please and check if it throws an error

import configparser

from TM1py import Cube, Dimension, TM1Service
from TM1py.Objects.Hierarchy import Hierarchy

config = configparser.ConfigParser()
config.read(r'config.ini')

cube = Cube(name="Py Cube", dimensions=("Py Dim1", "Py Dim2"))
dim1 = Dimension("Py Dim1")
hier1 = Hierarchy("Py Dim1", dimension_name="Py Dim1")
dim2 = Dimension("Py Dim2")
hier2 = Hierarchy("Py Dim2", dimension_name="Py Dim2")

for i in range(10):
    hier1.add_element("Elem " + str(i), "Numeric")
    hier2.add_element("Elem " + str(i), "Numeric")
dim1.add_hierarchy(hier1)
dim2.add_hierarchy(hier2)

with TM1Service(**config['tm1srv01']) as tm1:
    if tm1.cubes.exists("Py Cube"):
        tm1.cubes.delete(cube.name)
    if tm1.dimensions.exists("Py Dim1"):
        tm1.dimensions.delete("Py Dim1")
    tm1.dimensions.create(dim1)
    if tm1.dimensions.exists("Py Dim2"):
        tm1.dimensions.delete("Py Dim2")
    tm1.dimensions.create(dim2)
    tm1.cubes.create(cube)
    # write some values
    cells = {
        ("Elem 1", "Elem 2"): 10,
        ("Elem 5", "Elem 4"): 20
    }
    tm1.cubes.cells.write_values(cube.name, cells)
ToddGaluska commented 5 years ago

Interesting that it returned the same error. See below details. Thanks!

tm1version

<Response [204]> <Response [201]> <Response [201]> <Response [201]> Traceback (most recent call last): File "", line 16, in File "C:\Users\tg\AppData\Local\Programs\Python\Python37-32\lib\site-packages\TM1py\Services\CellService.py", line 126, in write_values return self._rest.POST(request=request, data=updates) File "C:\Users\tg\AppData\Local\Programs\Python\Python37-32\lib\site-packages\TM1py\Services\RESTService.py", line 30, in wrapper self.verify_response(response=response) File "C:\Users\tg\AppData\Local\Programs\Python\Python37-32\lib\site-packages\TM1py\Services\RESTService.py", line 214, in verify_response raise TM1pyException(response.text, status_code=response.status_code, reason=response.reason) TM1py.Exceptions.Exceptions.TM1pyException: Text: {"error":{"code":"278","message":"'Elem 1' can not be found in collection of type 'Element'."}} Status Code: 404 Reason: Not Found

ToddGaluska commented 5 years ago

Marius,

I dont know if the script could be executed more than once but when I tried to run again. Here is the error I got. Not sure if this helps.

TM1py.Exceptions.Exceptions.TM1pyException: Text: {"error":{"code":"278","message":"The default hierarchy of Dimension'(Py Dim1)' already exists."}} Status Code: 400 Reason: Bad Request

Thanks for working this with me.

MariusWirtz commented 5 years ago

Hi @ecapitaladvisors , now this is awkward. The simple script should run successfully against any model and any version of TM1 (> 10.2.2 FP 5). The script runs smoothly against my models too (same version: 11.4.00000.21). In fact it runs smoothly even when I execute it a second or third time.

I suppose you are using the latest version of TM1py (1.2.1), correct ? If yes, then there must be something wrong with your setup. Either the TM1 built has a bug or the model is "corrupted" (no idea how that could possibly happen).

I recommend to try your original script with a different TM1 model on a different machine with a different version of TM1.

ToddGaluska commented 5 years ago

tm1py version

Yes that is strange. I am using the latest version of TM1PY see attached. Give me some time to get another box to install this on since I will need to start from scratch. I also tried the below code. Its not what I am looking to do but this code did move data from Smartco IV to Smartco V.

import configparser config = configparser.ConfigParser() config.read(r'C:\Users\tgaluska\config.ini')

from datetime import datetime

from TM1py.Services import TM1Service

tm1_source = TM1Service(config['SmartCo IV']) tm1_target = TM1Service(config['SmartCo V'])

mdx = "SELECT " \ "{[Accounts IS].[Revenue]} on ROWS, " \ "{[Time].[2018-01]} on COLUMNS " \ "FROM [Income Statement] " \ "WHERE " \ "([Version].[Plan],[mIncome Statement].[Amount],[Organization].[Massachusetts])" data = tm1_source.data.execute_mdx(mdx)

values = [cell['Value'] for cell in data.values()]

tm1_target.data.write_values_through_cellset(mdx, values)

tm1_source.logout() tm1_target.logout()

ToddGaluska commented 5 years ago

tm1version_sandbox

Marius,

Got access to another box. See screenshot for details. I am going to work on building two identical models but wanted to let you know I did run. The code below and it return the error at the bottom. Not sure if this will help but its more information. Will write back once I have two models built that are identical.

import configparser

from TM1py import Cube, Dimension, TM1Service from TM1py.Objects.Hierarchy import Hierarchy

config = configparser.ConfigParser() config.read(r'C:\Users\tgaluska\config.ini') ['C:\Users\tgaluska\config.ini']

cube = Cube(name="Py Cube", dimensions=("Py Dim1", "Py Dim2")) dim1 = Dimension("Py Dim1") hier1 = Hierarchy("Py Dim1", dimension_name="Py Dim1") dim2 = Dimension("Py Dim2") hier2 = Hierarchy("Py Dim2", dimension_name="Py Dim2")

for i in range(10): ... hier1.add_element("Elem " + str(i), "Numeric") ... hier2.add_element("Elem " + str(i), "Numeric") ... dim1.add_hierarchy(hier1) ... dim2.add_hierarchy(hier2) ... with TM1Service(**config['Blank']) as tm1: ... if tm1.cubes.exists("Py Cube"): ... tm1.cubes.delete(cube.name) ... if tm1.dimensions.exists("Py Dim1"): ... tm1.dimensions.delete("Py Dim1") ... tm1.dimensions.create(dim1) ... if tm1.dimensions.exists("Py Dim2"): ... tm1.dimensions.delete("Py Dim2") ... tm1.dimensions.create(dim2) ... tm1.cubes.create(cube) ... # write some values ... cells = { ... ("Elem 1", "Elem 2"): 10, ... ("Elem 5", "Elem 4"): 20 ... } ... tm1.cubes.cells.write_values(cube.name, cells) ... Traceback (most recent call last): File "", line 6, in File "C:\Python37-32\lib\site-packages\TM1py\Services\DimensionService.py", li ne 45, in create raise e File "C:\Python37-32\lib\site-packages\TM1py\Services\DimensionService.py", li ne 37, in create response = self._rest.POST(request, dimension.body) File "C:\Python37-32\lib\site-packages\TM1py\Services\RESTService.py", line 32 , in wrapper self.verify_response(response=response) File "C:\Python37-32\lib\site-packages\TM1py\Services\RESTService.py", line 23 9, in verify_response raise TM1pyException(response.text, status_code=response.status_code, reason =response.reason) TM1py.Exceptions.Exceptions.TM1pyException: Text: {"error":{"code":"278","messag e":"An element with name \"Elem 0\" already exists. Failed to create element."}} Status Code: 400 Reason: Bad Request

MariusWirtz commented 5 years ago

Hi @ecapitaladvisors ,

please edit your last post and format the code like I did in a previous response, so that the code be copied and executed without guessing the indentations. I will check if I can reproduce.

ToddGaluska commented 5 years ago

Marius,

You were correct about the corruption of TM1 or the models on that server. Or possibly a version issue. I just got the data to move from GreatOutdoors to a Blank Greatoutdoors model on a new server. Should we continue with other test to dig deeper or consider this good? Thanks again for all the help! Working the weekend for me is appreciated.

MariusWirtz commented 5 years ago

Welcome! Happy to hear that it works. If you built something that could potentially be useful for other TM1py users you can push it to this repository. I'm happy to accept your Merge Request.

Unless I run into the same issue again at another TM1 setup I will not dig any deeper on it. This bug should be easy to spot for IBM. I assume it's probably already addressed.