Skip to content

Instantly share code, notes, and snippets.

@grenzi
Last active August 21, 2018 22:00
Show Gist options
  • Save grenzi/889066e07f5a72769ab3dc2b13baa72d to your computer and use it in GitHub Desktop.
Save grenzi/889066e07f5a72769ab3dc2b13baa72d to your computer and use it in GitHub Desktop.
runs a dax query against SSAS and returns a dataframe
import clr
import pandas as pd
from tqdm import tqdm
clr.AddReference("System.Data")
import System.Data.OleDb as ADONET
def handle_oledb_field(f):
mytype=str(type(f))
if mytype == "<class 'System.DBNull'>":
return None
if mytype == "<class 'int'>":
return int(f)
if mytype == "<class 'System.Decimal'>":
return float(f.ToString())
if mytype == "<class 'str'>":
return str(f)
raise "Unknown Type " + mytype
def dax_to_dataframe(daxcmd):
if "connection" not in dax_to_dataframe.__dict__: dax_to_dataframe.connection = None
connStr = r"Provider=MSOLAP;Persist Security Info=True;Initial Catalog=DBNAME;Data Source=SERVERNAME"
if dax_to_dataframe.connection is None:
connection = ADONET.OleDbConnection(connStr)
connection.Open()
command = connection.CreateCommand()
command.CommandText = daxcmd
reader = command.ExecuteReader()
schema_table = reader.GetSchemaTable()
#schema_table rows are query result columns
columns = []
for r in schema_table.Rows:
columns.append(r['ColumnName'])
rows = [None] * reader.get_RecordsAffected()
for x in tqdm(range(0, reader.get_RecordsAffected())):
reader.Read()
#https://docs.microsoft.com/en-us/dotnet/api/system.typecode?view=netframework-4.7.2
#but ints dont have them
#rows[x] = list( [ reader[c] if reader[c].GetTypeCode() != 2 else None for c in columns] )
rows[x] = list ( [ handle_oledb_field(reader[c]) for c in columns ] )
#connection.Close()
df = pd.DataFrame.from_records(columns=[c.replace('[', '_').replace(']', '_') for c in columns], data=rows, coerce_float=True)
del rows
del reader
return df
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment