Python - “KeyError : System.Object” - Pyadomd - Querying a SSAS Data Source [SOLVED]

半世苍凉 提交于 2020-06-01 05:10:48

问题


Working on a project where I am trying to query a SSAS data source we have at work through Python. The connection is presently within Excel files, but I am trying to reverse engineer the process with Python to automate part of the analysis I do on a day to day... I use the pyadomd library to connect to the data source, here`s my code:

clr.AddReference(r"C:\Program Files (x86)\Microsoft  Office\root\vfs\ProgramFilesX86\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.AdomdClient.dll")
clr.AddReference('Microsoft.AnalysisServices.AdomdClient')
from Microsoft.AnalysisServices.AdomdClient import AdomdConnection , AdomdDataAdapter
from sys import path
path.append('C:\Program Files (x86)\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.AdomdClient.dll')
import pyadomd
from pyadomd import Pyadomd
from pyadomd._type_code import adomd_type_map, convert

constr= "connection string"

with Pyadomd(constr) as conn:
    with conn.cursor().execute(query) as cur:
        print(cur.fetchall())

Which works (in part), seemingly I am able to connect to the SSAS data source. Say I do conn = Pyadomd(constr), it returns no error (no more as it did before). The issue is when I try to execute the query with the cursor it returns an error saying:

  File "C:\Users\User\Anaconda3\lib\site-packages\pyadomd\pyadomd.py", line 71, in execute
    adomd_type_map[self._reader.GetFieldType(i).ToString()].type_name

KeyError: 'System.Object'

By doing a bit of research, I found that KeyError meant that the code was trying to access a key within a dictionary in which that key isn't present. By digging through my variables and going through the code, I realized that the line:

 from pyadomd._type_code import adomd_type_map

Created this dictionary of keys:values: See dictionary here

Containing these keys: System.Boolean, System.DateTime, System.Decimal, System.Double, System.Int64, System.String. I figured that the "KeyError: System.Object" was referring to that dictionary. My issue is how can I import this System.Object key to that dictionary? From which library/module/IronPython Clr reference can I get it from?

What I tried:

clr.AddReference("System.Object")

Gave me error message saying "Unable to find assembly 'System.Object'. at Python.Runtime.CLRModule.AddReference(String name)"

I also tried:

from System import Object #no error but didn't work
from System import System.Object #error saying invalid syntax

I think it has to do with some clr.AddReference IronPython thing that I am missing, but I've been looking everywhere and can't find it.

Thanks!


回答1:


Glad that the newer version solved the problem.

A few comments to the code snippet above. It can be done a bit more concise 😊 Pyadomd will import the necessary classes from the AdomdClient, which means that the following lines can be left out.

clr.AddReference(r"C:\Program Files (x86)\MicrosoftOffice\root\vfs\ProgramFilesX86\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.AdomdClient.dll")
clr.AddReference('Microsoft.AnalysisServices.AdomdClient')
from Microsoft.AnalysisServices.AdomdClient import AdomdConnection , AdomdDataAdapter

Your code will then look like this:

import pandas as pd
from sys import path
path.append(r'C:\Program Files (x86)\MicrosoftOffice\root\vfs\ProgramFilesX86\Microsoft.NET\ADOMD.NET\130')

from pyadomd import Pyadomd

constr= "constring"
query = "query"

with Pyadomd(constr) as con:
    with con.cursor().execute(query) as cur:
        DF = pd.DataFrame(cur.fetchone(), columns = [i.name for i in cur.description])

The most important thing is to add the AdomdClient.dll to your path before importing the pyadomd package.

Furthermore, the package is mainly meant to be used with CPython version 3.6 and 3.7.




回答2:


Well big problems require big solutions..

After endlessly searching the web, I went on https://pypi.org/project/pyadomd/ and directly contacted the author of the package (SCOUT). Emailed him the same question and apparently there was a bug within the code that he fixed overnight and produced a new version of the package, going from 0.0.5 to 0.0.6. In his words:

[Hi,

Thanks for writing me 😊

I investigated the error, and you are correct, the type map doesn’t support converting System.Object.

That is a bug!

I have uploaded a new version of the Pyadomd package to Pypi which should fix the bug – Pyadomd will now just pass a System.Object type through as a .net object. Because Pyadomd doesn’t know the specifics of the System.Object type at runtime, you will then be responsible yourself to convert to a python type if necessary.

Please install the new version using pip.]1

So after running a little pip install pyadomd --upgrade, I restarted Spyder and retried the code and it now works and I can query my SSAS cube !! So hopefully it can help others.

Snippet of the code:

import pandas as pd
import clr
clr.AddReference(r"C:\Program Files (x86)\MicrosoftOffice\root\vfs\ProgramFilesX86\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.AdomdClient.dll")
clr.AddReference('Microsoft.AnalysisServices.AdomdClient')
from Microsoft.AnalysisServices.AdomdClient import AdomdConnection , AdomdDataAdapter
from sys import path
path.append(r'C:\Program Files (x86)\MicrosoftOffice\root\vfs\ProgramFilesX86\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.Ado mdClient.dll')
import pyadomd
from pyadomd import Pyadomd

constr= "constring"
query = "query"

and then as indicated on his package website:

with Pyadomd(constr) as con:
    with con.cursor().execute(query) as cur:
        DF = pd.DataFrame(cur.fetchone(), columns = [i.name for i in cur.description])

and bam! 10795 rows by 39 columns DataFrame, I haven't precisely calculated time yet, but looking good so far considering the amount of data.



来源:https://stackoverflow.com/questions/62012135/python-keyerror-system-object-pyadomd-querying-a-ssas-data-source-sol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!