Запрос SSAS MDX в Python (библиотека adodbapi) с динамическим c параметром '?' - PullRequest
0 голосов
/ 26 марта 2020

Я использую библиотеку adodbapi python для запроса куба SSAS. По сути, моя цель - попросить пользователя сначала ввести идентификатор учетной записи. Затем я хотел бы, чтобы он передавался как параметр динамически в разделе WHERE запроса с ? и включал аргумент в cur.execute() часть кода, как указано в документации, которую я привел ниже. cur.execute() - это место, где я получаю ошибку, и я также скопировал и вставил большую часть ошибки ниже.

Я сузил проблему до того факта, что параметр не работает. Параметры Dynami c хорошо работают для меня с PyODBC и pd.read_sql, но, похоже, они не работают с adodbapi, который я должен использовать, поскольку это единственная библиотека, с которой я когда-либо успешно запрашивал куб SSAS из python.

import adodbapi
import numpy as np
import pandas

account_id_input = input("Select Account ID: ").strip()

def get_df(data):
    ar = np.array(data.ado_results) # turn ado results into a numpy array
    df = pd.DataFrame(ar).transpose() # create a dataframe from the array
    return df


with adodbapi.connect('''Provider=MSOLAP;
Data Source=MyServerName;
Initial Catalog=MySSASModel;
User ID=MyUserLogin;
Password=MyPassword;
Persist Security Info=True;
Impersonation Level=Impersonate''', 7200) as con:
    with con.cursor() as cur:
        sql_str = r'''SELECT
NON EMPTY
{
[Measures].[Revenue]
}
ON COLUMNS,

NON EMPTY
[AccountTable].[Year-Month].[Year-Month]

ON ROWS
FROM [Model]
WHERE([AccountTable].[Account Number].[?])
'''
        args = [account_id_input]
        cur.execute(sql_str, args)
        data = cur.fetchall()
        df = get_df(data)
        df.columns = ['Year-Month','Revenue']
df

---------------------------------------------------------------------------
com_error                                 Traceback (most recent call last)
~\.conda\envs\ProgramData\lib\site-packages\adodbapi\adodbapi.py in _execute_command(self)
    681             else: #pywin32
--> 682                 recordset, count = self.cmd.Execute()
    683             # ----- ------------------------------- ---

~\.conda\envs\ProgramData\lib\site-packages\win32com\client\dynamic.py in Execute(self, RecordsAffected, Parameters, Options)

~\.conda\envs\ProgramData\lib\site-packages\win32com\client\dynamic.py in _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, resultCLSID, *args)
    286         def _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, resultCLSID, *args):
--> 287                 result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
    288                 return self._get_good_object_(result, user, resultCLSID)

com_error: (-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for Analysis Services.', 'The following system error occurred:  The parameter is incorrect. ', None, 0, -2147467259), None)

During handling of the above exception, another exception occurred:

DatabaseError                             Traceback (most recent call last)
<ipython-input-51-87576a978d18> in <module>
     35 '''
     36         args = [account_id_input]
---> 37         cur.execute(sql_str, args)
     38 #         data = cur.fetchall()
     39 #         df = get_df(data)

~\.conda\envs\ProgramData\lib\site-packages\adodbapi\adodbapi.py in execute(self, operation, parameters)
    873         if verbose > 3:
    874             print('Params=', format_parameters(self.cmd.Parameters, True))
--> 875         self._execute_command()
    876 
    877     def executemany(self, operation, seq_of_parameters):

~\.conda\envs\ProgramData\lib\site-packages\adodbapi\adodbapi.py in _execute_command(self)
    688                                                             format_parameters(self.cmd.Parameters, True))
    689             klass = self.connection._suggest_error_class()
--> 690             self._raiseCursorError(klass, _message)
    691         try:
    692             self.rowcount = recordset.RecordCount

~\.conda\envs\ProgramData\lib\site-packages\adodbapi\adodbapi.py in _raiseCursorError(self, errorclass, errorvalue)
    561         if eh is None:
    562             eh = api.standardErrorHandler
--> 563         eh(self.connection, self, errorclass, errorvalue)
    564 
    565     def build_column_info(self, recordset):

~\.conda\envs\ProgramData\lib\site-packages\adodbapi\apibase.py in standardErrorHandler(connection, cursor, errorclass, errorvalue)
     55             cursor.messages.append(err)
     56         except: pass
---> 57     raise errorclass(errorvalue)
     58 
     59 # Note: _BaseException is defined differently between Python 2.x and 3.x

DatabaseError: (-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for Analysis Services.', 'The following system error occurred:  The parameter is incorrect. ', None, 0, -2147467259), None)
Command:

Я перепробовал все и у меня нет идей. Я ссылался на этот документ: http://adodbapi.sourceforge.net/quick_reference.pdf и некоторые другие посты stackoverflow, которые были похожи: введите описание ссылки здесь , но я не мог понять это! Мой MDX ужасен, если у кого-то еще есть идеи о том, как я могу переписать запрос MDX, чтобы он лучше работал с adodbapi с точки зрения параметров Dynami c, если это действительно проблема с библиотекой.

...