Lodrik
Lodrik

Reputation: 639

Connect to an OLAP Cube using Python on LINUX

I know how to connect to a MS OLAP cube using Python on Windows - well, at least one method :-).

Usually I use the win32py package and invoke a .COM object to connect:

import win32com.client
connection = win32com.client.Dispatch(r'ADODB.Connection')
connString = 'Connection String to MSOLAP CUBE'
connection.Open(connString)

However, now I want to do the same with Linux (RHEL 7.2), and I have no idea how to do that. Can you please help me with that?

What I tried so far:

I tried using pyodbc-package or the sqlalchemy to establish a connection, but was not really successful in doing so (see Edit-1 section). Moreover, I am not even sure if I am looking at the right packages, or if it is even possible at all to connect to a MS OLAP cube on Linux :S

What I found so far:

On Windows I usually use a .COM object or the .NET framework to connect to the cube. However, if I understand it right, these are Windows specific languages/frameworks, and can't be used on Linux. Right now I am looking at Mono for Linux, to see if I can use it to establish the connection.

More information:

Python version: 3.4

Linux distribution: Red Hat Enterprise Linux 7.2

sudo privileges on the machine: yes

.

Edit-1 (see: shellter comment)

I tried three different methods till now, but as mentioned above, I am not even sure if I work in the right direction. The only thing I am confident in, is that I can't establish a connection to the Cube via a .COM object (like in the Windows case), as Linux does not support the .COM environment.

Code-1:

import pyodbc
server = 'server address'
database = 'database name'
connStr = 'Provider=MSOLAP;Data Source=' + server + ';Initial Catalog=' + database + '; Application Name=Python;'
pyodbc.connect(connStr)

Error-1:

File "C:/Users/Desktop/untitled/main.py", line 35, in <module> 
File connStr(connStr)

File TypeError: 'str' object is not callable

Code-2:

import pyodbc

driver = '{MSOLAP}'
server = 'server address’
database = 'database name'
user = ‘user name’
passw = 'password'
connStr = "Provider=MSOLAP;Data Source=" + server + ";Initial Catalog=" + database + "; Application Name=Python;"

Error-2:

File "C:/Users/besechr/Desktop/untitled/main.py", line 19, in <module>
pyodbc.connect('DRIVER=' + driver + ';SERVER=' + server + ';DATABASE=' + database + ';UID=' + user + ';PWD=' + passw)

pyodbc.Error: ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')

btw: if I try to connect to the underlying SQL server with the above-stated connection string (changing the driver parameter to {SQL Server}) it works fine.

Code-3:

import pyodbc
import sqlalchemy

engine = sqlalchemy.create_engine('mssql+pyodbc://' + server )
engine.connect()

Error-3:

sqlalchemy.exc.DBAPIError: (Error) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)') None None

Upvotes: 5

Views: 4758

Answers (1)

Supun De Silva
Supun De Silva

Reputation: 1487

I had the same requirement.

We were running on Ubuntu 20.04.

Attempt 1

  • We Needed Python.Net latest Stable

  • This needed Mono As a Dependancy

  • Mono only supported .NetFW4.xx integration

  • We used standard installation of Python.Net (which was also .NetFW4.xx support)

  • Hence we HAD to use The specific lib Microsoft.AnalysisServices.AdomdClient.retail.amd64 Which is Windows compatible only

  • If we used microsoft.analysisservices.adomdclient.netcore.retail.amd64 it fails with no proper errors

  • Also All the packages had to be placed inside Monos package store. Else it failed to find them.

Finally it failed saying

EntryPointNotFoundException: GetConsoleWindow assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) Microsoft.AnalysisServices.AdomdClient.Interop.NativeMethods.GetConsoleWindow()
  at Microsoft.AnalysisServices.AdomdClient.Utilities.WindowsRuntimeHelper.IsProcessWithUserInterface () [0x00018] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.Configuration.ConfigurationHelper.CheckIfProcessWithUserInterface () [0x00009] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.Configuration.RuntimeConfiguration..ctor (System.Collections.Generic.IDictionary`2[TKey,TValue] configuration) [0x0000a] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.Configuration.ConfigurationHelper.EnsureConfigurationIsLoaded () [0x00034] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.Configuration.ConfigurationHelper.get_Connectivity () [0x00000] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.XmlaClient.GetTcpClient (Microsoft.AnalysisServices.AdomdClient.Hosting.IConnectivityOwner owner, Microsoft.AnalysisServices.AdomdClient.ConnectionInfo connectionInfo) [0x000ee] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenTcpConnection (Microsoft.AnalysisServices.AdomdClient.ConnectionInfo connectionInfo, Microsoft.AnalysisServices.AdomdClient.Sspi.SecurityMode securityMode) [0x00025] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenConnectionAndCheckIfSessionTokenNeeded (Microsoft.AnalysisServices.AdomdClient.ConnectionInfo connectionInfo) [0x0005a] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.XmlaClient+<>c__DisplayClass95_0.<OpenConnection>b__0 () [0x00000] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.Security.TransparentUserContext.ExecuteInUserContextImpl[TResult] (System.Func`1[TResult] action) [0x00000] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.Security.UserContext.ExecuteInUserContext[TResult] (System.Func`1[TResult] action) [0x00006] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenConnection (Microsoft.AnalysisServices.AdomdClient.ConnectionInfo connectionInfo, System.Boolean& isSessionTokenNeeded) [0x00020] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.XmlaClient.Connect (Microsoft.AnalysisServices.AdomdClient.ConnectionInfo connectionInfo, System.Boolean beginSession) [0x002c6] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.AdomdConnection+XmlaClientProvider.Connect () [0x00064] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.AdomdConnection+XmlaClientProvider.Microsoft.AnalysisServices.AdomdClient.AdomdConnection.IXmlaClientProviderEx.ConnectXmla () [0x00000] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.ConnectToXMLA (System.Boolean createSession, System.Boolean isHTTP) [0x00072] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.Open () [0x000b9] in <d13c74b6ccb34cf09a1af7bf07e15252>:0 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <533173d24dae460899d2b10975534bb0>:0 

Cause

Folks smarter than me had explained here what is going on
C# to Mono GetConsoleWindow Exception

Attempt 2

Set the runtime with clr_loader that is installed as a dependancy of pythonnet

from clr_loader import get_coreclr
from pythonnet import set_runtime

rt = get_coreclr("path_to_runtime_cong/net_core_rt_conf.json")
set_runtime(rt)

import clr

My Conf Looked like

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.3"
    }
  }
}

Extracted the microsoft.analysisservices.adomdclient.netcore.retail.amd64 nuget package in to GAC of the .netCore installation on the Nix Box (call this pkg_path)

Then Tryied to connect

import pandas as pd
from sys import path
path.append(**pkg_path**)

clr.AddReference('System.Data')
clr.AddReference('Microsoft.AnalysisServices.AdomdClient')
from Microsoft.AnalysisServices.AdomdClient import AdomdConnection, AdomdDataAdapter

conn = AdomdConnection("Data Source=<MY_SERVER>;Catalog=<MY_CUBE>;")
conn.Open()

And I was greeted with

NotSupportedException: This feature is supported for a .NET Core client only on Windows systems.
---------------------------------------------------------------------------
NotSupportedException                     Traceback (most recent call last)
<command-3652263429411005> in <module>
     10 
     11 conn = AdomdConnection("Data Source=<MY_SERVER>;Catalog=<MY CUBE>;")
---> 12 conn.Open()
     13 cmd = conn.CreateCommand()
     14 cmd.CommandText = MDX_QUERY

NotSupportedException: This feature is supported for a .NET Core client only on Windows systems.
   at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenConnectionAndCheckIfSessionTokenNeeded(ConnectionInfo connectionInfo)
   at Microsoft.AnalysisServices.AdomdClient.XmlaClient.<>c__DisplayClass94_0.<OpenConnection>b__0()
   at Microsoft.AnalysisServices.Security.TransparentUserContext.ExecuteInUserContextImpl[TResult](Func`1 action)
   at Microsoft.AnalysisServices.Security.UserContext.ExecuteInUserContext[TResult](Func`1 action)
   at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenConnection(ConnectionInfo connectionInfo, Boolean& isSessionTokenNeeded)

In a nutshell as of now this seems a bit impossible. At least in a straight forward manner.

Upvotes: 1

Related Questions