Closed harveyca307 closed 3 years ago
Hi, @harveyca307 Could you verify all all subsets have been created successfully on the target server? Or some elements don't exist in some dimension on the target server which the soure view is using? Thanks.
I verified that the dimensions are the same, and cube exists in both places. There is only one named subset for this test which is on the plan_Source dimension from PlanSamp
source_view = source_tm1.cubes.views.get(cube_name=cube, view_name=view, private=False)
target_tm1.cubes.views.create(view=source_view, private=False)
The views.create is the line causing the problem
On Thu, May 13, 2021, 6:26 PM tm1sir @.***> wrote:
- Has that only subset been created sucessfully on that target? Is the source view using the subset?
- If yes, what if you just use the following the code to copy the view?
source_view = source_tm1.cubes.views.get(cube_name=cube, view_name=view, private=False)target_tm1.cubes.views.create(view=source_view, private=False)
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cubewise-code/tm1py/issues/541#issuecomment-840891572, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOD7AY73PTTQIFPCH6TBIHTTNRN2DANCNFSM443LRSFQ .
In the Exception it says: Selected element was not specified on Title axis subset.
Could it be, that you are trying to migrate a view that has no selected element in a title?
I guess the scenario could be that you have an existing view with an element like Product ABC
and then later you delete Product ABC
from the dimension. Then the view is kinda "broken" and it could be that the REST API wouldn't accept the approach to create a view that has this "broken" state.
I checked this morning and there were no subsets with missing elements. I did only have one named subset being used in the view, so I created a named subset for every dimension. My thought was that maybe I was running up against a issue using default subsets. The subsets all get created just fine. The view create line seems to throw an error after running the function to create/update the subsets:
target_tm1.cubes.views.create(view=source_view, private=False)
The subsets are all public and have elements in them. The dimensions were copied to each instance from PlanSamp so they are identical. Next step is to debug until TM1py tries to execute the POST to create the view?
Yes and see if you can catch the actual response from the TM1 server. This was likely covered in other replies but worth mentioning anyway. There are a number of things that worked in Native Views that break over the REST API
From: Chad Harvey @.> Reply-To: cubewise-code/tm1py @.> Date: Monday, May 17, 2021 at 9:20 AM To: cubewise-code/tm1py @.> Cc: Subscribed @.> Subject: Re: [cubewise-code/tm1py] Issue with copying view (#541)
I checked this morning and there were no subsets with missing elements. I did only have one named subset being used in the view, so I created a named subset for every dimension. My thought was that maybe I was running up against a issue using default subsets. The subsets all get created just fine. The view create line seems to throw an error after running the function to create/update the subsets:
target_tm1.cubes.views.create(view=source_view, private=False)
The subsets are all public and have elements in them. The dimensions were copied to each instance from PlanSamp so they are identical. Next step is to debug until TM1py tries to execute the POST to create the view?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/cubewise-code/tm1py/issues/541#issuecomment-842457325, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEK7GZQXUEMDIBEWK5GUMATTOE62NANCNFSM443LRSFQ.
Source view:
JSON:
Stack Trace:
The error says you don't have anything selected on titles. This is likely due to the fact that views created in perspectives are not always Rest compatible.
Sent from my mobile phone
On May 18, 2021 4:01 PM, Chad Harvey @.***> wrote:
Source view: [image]https://user-images.githubusercontent.com/59240547/118733851-c33e0880-b802-11eb-9a45-e12e62a3df51.png
JSON: [image]https://user-images.githubusercontent.com/59240547/118733898-da7cf600-b802-11eb-9c47-e5b59d337840.png
Stack Trace: [image]https://user-images.githubusercontent.com/59240547/118733938-ea94d580-b802-11eb-8fdd-2af27cd90731.png
- You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/cubewise-code/tm1py/issues/541#issuecomment-843621916, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEK7GZT5F6Y475OJA2QBT63TOLWSNANCNFSM443LRSFQ.
A screenshot of the opened view in architect would be interesting
Architect View Screenshot:
PAW Created view:
Different Stack Trace for PAW View:
C:\Users\charvey\PycharmProjects\TM1_Promote\venv\Scripts\python.exe C:/Users/charvey/PycharmProjects/TM1_Promote/ztemp.py
Traceback (most recent call last):
File "C:\Users\charvey\PycharmProjects\TM1_Promote\ztemp.py", line 28, in <module>
dimensions = source_view._titles
AttributeError: 'MDXView' object has no attribute '_titles'
Process finished with exit code 1
The view created from PAW is an MDXView
. It needs to be treated differently. This explains the error in your last post. The MDXView
doesn't have rows
, columns
, titles
properties like the NativeView
does
Based on the screenshot from Architect, I can't see what's wrong with the view setup. I think it's either, something unsupported in the REST API like @rclapp already pointed out or the selected element doesn't exist in the target instance.
In looking at the Debug window, I am seeing something that looks odd:
Dimensions 5 and 6 are Row and Column dimensions in the Native view (opened plan_BudgetPlan, hit save view). Could this be causing my issue where it thinks that my dimension is on the Row and Title space?
Grabbed the source view by:
source_view = source_tm1.cubes.views.get(cube_name=cube, view_name=view, private=False)
Something must be wrong with the view. Can you please post the JSON definition of the view here?
from TM1py import TM1Service
with TM1Service(address='localhost', port=12354, ssl=True, user="admin", password="apple") as tm1:
view = tm1.views.get("c1", "v1", private=False)
print(str(view))
Below is the output of
print(str(source_view))
{"@odata.type": "ibm.tm1.api.v1.NativeView","Name": "Chad","Columns":[{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_time')/Hierarchies('plan_time')", "Elements@odata.bind": ["Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Description')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jan-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Feb-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Mar-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Apr-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('May-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jun-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jul-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Aug-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Sep-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Oct-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Nov-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Dec-2003')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jan-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Feb-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Mar-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Apr-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('May-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jun-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jul-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Aug-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Sep-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Oct-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Nov-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Dec-2004')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jan-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Feb-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Mar-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Apr-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('May-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jun-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Jul-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Aug-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Sep-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Oct-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Nov-2005')", "Dimensions('plan_time')/Hierarchies('plan_time')/Elements('Dec-2005')"]}}],"Rows":[{"Subset@odata.bind": "Dimensions('plan_source')/Hierarchies('plan_source')/Subsets('Chad')"}],"Titles":[{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_version')/Hierarchies('plan_version')", "Elements@odata.bind": ["Dimensions('plan_version')/Hierarchies('plan_version')/Elements('FY 2003 Budget')", "Dimensions('plan_version')/Hierarchies('plan_version')/Elements('FY 2004 Budget')", "Dimensions('plan_version')/Hierarchies('plan_version')/Elements('FY 2004 Forecast')", "Dimensions('plan_version')/Hierarchies('plan_version')/Elements('FY 2005 Budget-baseline')", "Dimensions('plan_version')/Hierarchies('plan_version')/Elements('FY 2005 Budget-upside')"]}, "Selected@odata.bind": "Dimensions('plan_version')/Hierarchies('plan_version')/Elements('FY 2003 Budget')"},{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')", "Elements@odata.bind": ["Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Elements('10000')", "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Elements('10100')", "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Elements('10200')", "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Elements('10300')", "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Elements('10400')"]}, "Selected@odata.bind": "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Elements('10000')"},{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_department')/Hierarchies('plan_department')", "Elements@odata.bind": ["Dimensions('plan_department')/Hierarchies('plan_department')/Elements('1000')", "Dimensions('plan_department')/Hierarchies('plan_department')/Elements('100')", "Dimensions('plan_department')/Hierarchies('plan_department')/Elements('200')", "Dimensions('plan_department')/Hierarchies('plan_department')/Elements('300')", "Dimensions('plan_department')/Hierarchies('plan_department')/Elements('400')"]}, "Selected@odata.bind": "Dimensions('plan_department')/Hierarchies('plan_department')/Elements('1000')"},{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')", "Elements@odata.bind": ["Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Elements('Net Operating Income')", "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Elements('Revenue')", "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Elements('COS')", "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Elements('Operating Expense')"]}, "Selected@odata.bind": "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Elements('Net Operating Income')"},{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')", "Elements@odata.bind": ["Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('local')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('beginning')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('ending')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('planning')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('spot')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('actual')"]}, "Selected@odata.bind": "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('local')"}],"SuppressEmptyColumns": false,"SuppressEmptyRows":false,"FormatString": "0.#########"}
I can't reproduce the issue. When I post the JSON against my local Planning Sample model, it fails with:
{
"error": {
"code": "278",
"message": "'Description' can not be found in collection of type 'Element'."
}
}
After I created the element Description
in the plan_time
dimension it failed with:
{
"error": {
"code": "278",
"message": "'Chad' can not be found in collection of type 'Subset'."
}
}
After I created the Chad
subset, the view was created successfully.
It must be related to your version or setup. Please post the latest error and stack trace again.
Stack Trace:
C:\Users\charvey\PycharmProjects\TM1_Promote\venv\Scripts\python.exe C:/Users/charvey/PycharmProjects/TM1_Promote/ztemp.py
Traceback (most recent call last):
File "C:\Users\charvey\PycharmProjects\TM1_Promote\ztemp.py", line 41, in
Process finished with exit code 1
View JSON:
{"@odata.type": "ibm.tm1.api.v1.NativeView","Name": "Chad","Columns":[{"Subset@odata.bind": "Dimensions('plan_time')/Hierarchies('plan_time')/Subsets('Default')"}],"Rows":[{"Subset@odata.bind": "Dimensions('plan_source')/Hierar
chies('plan_source')/Subsets('Chad')"}],"Titles":[{"Subset@odata.bind": "Dimensions('plan_version')/Hierarchies('plan_version')/Subsets('Default')", "Selected@odata.bind": "Dimensions('plan_version')/Hierarchies('plan_version')
/Elements('FY 2003 Budget')"},{"Subset@odata.bind": "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Subsets('Default')", "Selected@odata.bind": "Dimensions('plan_business_unit')/Hierarchies('plan_business_un
it')/Elements('10000')"},{"Subset@odata.bind": "Dimensions('plan_department')/Hierarchies('plan_department')/Subsets('Default')", "Selected@odata.bind": "Dimensions('plan_department')/Hierarchies('plan_department')/Elements('10
00')"},{"Subset@odata.bind": "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Subsets('Default')", "Selected@odata.bind": "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/El
ements('Revenue')"},{"Subset": {"Hierarchy@odata.bind": "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')", "Elements@odata.bind": ["Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Eleme
nts('local')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('beginning')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('ending')", "Dimensions('plan_exchange_
rates')/Hierarchies('plan_exchange_rates')/Elements('planning')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('spot')", "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/El
ements('actual')"]}, "Selected@odata.bind": "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Elements('local')"}],"SuppressEmptyColumns": false,"SuppressEmptyRows":false,"FormatString": "0.#########"}
You are missing a subset called Default
in one of the dimensions
Sorry had some code commented out. I also recreated view in Architect so that each dimension had a static named subset that was not the Default subset. Running PA Local 2.0.9.8 and PAW Local 2.0.63.
Stack trace:
C:\Users\charvey\PycharmProjects\TM1_Promote\venv\Scripts\python.exe C:/Users/charvey/PycharmProjects/TM1_Promote/ztemp.py
Traceback (most recent call last):
File "C:\Users\charvey\PycharmProjects\TM1_Promote\ztemp.py", line 41, in
Process finished with exit code 1
Cube View JSON:
{"@odata.type": "ibm.tm1.api.v1.NativeView","Name": "Chad","Columns":[{"Subset@odata.bind": "Dimensions('plan_time')/Hierarchies('plan_time')/Subsets('Subset1')"}],"Rows":[{"Subset@odata.bind": "Dimensions('plan_source')/Hierar
chies('plan_source')/Subsets('Subset1')"}],"Titles":[{"Subset@odata.bind": "Dimensions('plan_version')/Hierarchies('plan_version')/Subsets('Subset1')", "Selected@odata.bind": "Dimensions('plan_version')/Hierarchies('plan_versio
n')/Elements('FY 2003 Budget')"},{"Subset@odata.bind": "Dimensions('plan_business_unit')/Hierarchies('plan_business_unit')/Subsets('Subset1')", "Selected@odata.bind": "Dimensions('plan_business_unit')/Hierarchies('plan_business
_unit')/Elements('10000')"},{"Subset@odata.bind": "Dimensions('plan_department')/Hierarchies('plan_department')/Subsets('Subset1')", "Selected@odata.bind": "Dimensions('plan_department')/Hierarchies('plan_department')/Elements(
'1000')"},{"Subset@odata.bind": "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')/Subsets('Subset1')", "Selected@odata.bind": "Dimensions('plan_chart_of_accounts')/Hierarchies('plan_chart_of_accounts')
/Elements('Revenue')"},{"Subset@odata.bind": "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates')/Subsets('Subset1')", "Selected@odata.bind": "Dimensions('plan_exchange_rates')/Hierarchies('plan_exchange_rates'
)/Elements('local')"}],"SuppressEmptyColumns": false,"SuppressEmptyRows":false,"FormatString": "0.#########"}
Script code:
from TM1py.Services import TM1Service
from configparser import ConfigParser
config = ConfigParser()
config.read(r'config.ini')
source_tm1 = TM1Service(**config['psamp'], password='somepass')
target_tm1 = TM1Service(**config['glcs'], password='somepass')
cube = 'plan_BudgetPlan'
view = 'Chad'
def copy_subs(sub_dict: dict) -> str:
for _object in sub_dict:
dimension = _object
subset = sub_dict[_object]
source_sub = source_tm1.dimensions.subsets.get(dimension_name=dimension, hierarchy_name=dimension,
subset_name=subset, private=False)
if target_tm1.dimensions.subsets.exists(dimension_name=dimension, hierarchy_name=dimension,
subset_name=subset, private=False):
target_tm1.dimensions.subsets.update(subset=source_sub, private=False)
else:
target_tm1.dimensions.subsets.create(subset=source_sub, private=False)
return "Some string"
source_view = source_tm1.cubes.views.get(cube_name=cube, view_name=view, private=False)
# print(str(source_view))
dimensions = source_view._titles
dimensions.extend(source_view.rows)
dimensions.extend(source_view.columns)
sub_list = dict()
for dim in dimensions:
if dim.subset.name:
sub_list[dim.dimension_name] = dim.subset.name
if sub_list:
copy_subs(sub_list)
if target_tm1.cubes.views.exists(cube_name=cube, view_name=view, private=False):
target_tm1.cubes.views.update(view=source_view, private=False)
else:
target_tm1.cubes.views.create(source_view, private=False)
Target Cube before running script:
Source View in Architect:
Target Cube after script:
It created the subsets, but failed on the View create. Each subset has one element and is static.
Did some more digging. If I run the 2 processes separately (Copy_Subs, then Copy View in 2 separate runs) it works. Talking to a colleague it seems that there might be a need to disconnect and reconnect to the API after creating/updating the Subsets. Testing that now...
OK. It could well be that TM1 needs some digesting time between certain operations. I have seen this before. Perhaps sleeping for a second or two, between creating the subsets and creating the views would be enough.
Added a sleep for anywhere from 10-30 seconds with no success. I am hearing that a possible logout and reconnect is necessary. So I am thinking a tm1.logout followed by a new connection request? tm1 = TM1Service(.....?
@harveyca307,
since you have a reproducible case it's best to report this directly to IBM. I think that's a bug within TM1.
The issue isn't with the REST API, it has to do with those two ViewAxisSelection objects that are being added into the view.titles list. This happens in your code when you do this:
dimensions = source_view.titles
dimensions.extend(source_view.rows)
dimensions.extend(source_view.columns)
The dimensions variable is just a reference to the source_view.titles so when you extend the list with the source_view.rows and source_view.columns, those ViewAxisSelection objects are being added to the source_view.titles list. When you use the view.create() function and it creates the url for the api, the ViewAxisSelection objects are appended to the title area but since they have no selected element you get the "Selected element was not specified on Title axis subset" error when the request is sent.
To fix this error just make sure you create a new list in memory so that you aren't mutating the source_view object.
Thanks @tmonty12.
@harveyca307
Please change the code to dimensions = list(source_view.titles)
and let us know how it goes.
Describe what did you try to do with TM1py I am trying to copy a view and any named subsets from a Source server to a target server
Describe what's not working the way you expect Didn't get the expected result? Describe:
Version
Additional context Script:
Stack Trace: