SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server 2017 RC2 の ML Services で Python のチュートリアルを実行する場合の注意点

leave a comment

本投稿は、2017/9/3 時点の最新の製品前リリースである SQL Server 2017 RC2 に限定された内容です
In-Database Python Analytics for SQL Developers の内容を SQL Server 2017 RC2 で実行しようとした際の注意点を。
「import pandas」の内容については、フィードバックしたところ把握されている不具合らしく、RC2 限定の内容となるかと。
ドキュメントバグについては、コメントで指摘されているので、後日修正されるかと。

最初は、冒頭で紹介したチュートリアルを「revoscalepy」のパッケージを使用した場合の問題です。
いくつかのコードで、「rx_logit_ex」という関数が使用されていますが、RC2 の「revoscalepy」には、この関数は含まれていません。
この関数は次のようにインポートされています。

from revoscalepy.functions.RxLogit import rx_logit_ex

 
「”PYTHON_SERVICES\Lib\site-packages\revoscalepy\functions\RxLogit.py」を確認してみると、次のような定義が行われています。

def rx_logit(formula: str,
                data: Union[RxDataSource, DataFrame],
                pweights: str = None,
                fweights: str = None,

「rx_logit_ex」は存在しておらず、「rx_logit」が正しい定義となりますので、「_ex」付きの関数を使用している場合は修正する必要があります。
コメントを眺めていたところ指摘が行われていましたので、そのうち修正されるかと。
もう 1 点が「import pandas」が記載されている箇所になります。
外部スクリプトとして、次のようなシンプルなクエリを実行してみます。

exec sp_execute_external_script @language =N'Python',
@script=N'
import pandas
'

RC2 では、このようなシンプルなスクリプトでも次のようなエラーとなります…。

メッセージ 39004、レベル 16、状態 20、行 0
‘sp_execute_external_script’ に HRESULT 0x80004004 を指定して実行中に、’Python’ スクリプト エラーが発生しました。
メッセージ 39019、レベル 16、状態 2、行 0
外部スクリプトエラーが発生しました:
Error in execution.? Check the output for more information.
Traceback (most recent call last):
File “<string>”, line 5, in <module>
File “C:\PROGRA~1\MICROS~1\MSSQL1~1.SQL\MSSQL\EXTENS~1\SQLEXPRESS01\4477531C-1AD6-4481-8190-80036B466985\sqlindb.py”, line 24, in transform
OutputDataSet = pandas.DataFrame()
UnboundLocalError: local variable ‘pandas’ referenced before assignment
SqlSatelliteCall error: Error in execution.? Check the output for more information.
外部スクリプトからの STDOUT メッセージ:
Express Edition will continue to be enforced.
SqlSatelliteCall function failed. Please see the console output for more information.
Traceback (most recent call last):
File “C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py”, line 406, in rx_sql_satellite_call
rx_native_call(“SqlSatelliteCall”, params)
File “C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\PYTHON_SERVICES\lib\site-packages\revoscalepy\RxSerializable.py”, line 286, in rx_native_call
ret = px_call(functionname, params)
RuntimeError: revoscalepy function failed.

RC2 では、Python のスクリプトを実行した際には、記載したスクリプトが単純に実行されるのではなく、SQL Server のインスタンスをインストールしたディレクトリの「ExtensibilityData」配下に「sqlindb.py」という Python のファイルが生成されています。
スクリプトの実行が完了する前であれば、ファイルが存在している状態となっていますので、ファイルを引っこ抜いてみました。

from revoscalepy.utils.RxOptions import RxOptions
import os
import pandas
import collections
def initialize():
    global result
    RxOptions.set_option('isInSqlServer', True)
    RxOptions.set_option('inDatabaseHostPlatform', int(0))
    _sessionDirectory = 'C:\\\\PROGRA~1\\\\MICROS~1\\\\MSSQL1~1.SQL\\\\MSSQL\\\\EXTENS~1\\\\SQLEXPRESS01\\\\4477531C-1AD6-4481-8190-80036B466985'
    os.chdir(_sessionDirectory)
    os.environ['APPDATA'] = _sessionDirectory
    os.environ['HOMEPATH'] = _sessionDirectory
    os.environ['LOCALAPPDATA'] = _sessionDirectory
    os.environ['TEMP'] = _sessionDirectory
    os.environ['TMP'] = _sessionDirectory
    os.environ['USERPROFILE'] = _sessionDirectory
    result = { 'result' : pandas.DataFrame().to_dict('list'), 'arguments' : {} }
def transform():
    global result
    OutputDataSet = pandas.DataFrame()
    from revoscalepy.RxSerializable import parse_result_dataframe
    InputDataSet = parse_result_dataframe(DataSet['data'])
         import pandas
    if not isinstance(OutputDataSet, pandas.DataFrame):
        raise TypeError('OutputDataSet should be of type pandas.DataFrame')
    if (len(OutputDataSet.columns) != len(set(OutputDataSet.columns))):
        raise TypeError('duplicate column names in OutputDataSet are not allowed')
    resultOrdered = collections.OrderedDict()
    for column in OutputDataSet.columns: resultOrdered[str(column)] = list(OutputDataSet[column].values)
    result = { 'result' : resultOrdered, 'arguments' : {} }

 
スクリプト内で記載した内容が「transform」関数内に展開されるようなのですが、「import pandas」が展開されている場所がよろしくないみたいですね…。
スクリプトの先頭に「import pandas」が定義されていますので、「sp_execute_external_script」内の「import pandas」については、ひとまずコメント化しておいても動作しそうでした。
(import pandas as pd というような別名でインポートすることでも回避できそうですが)
リリース候補版特有の問題だと思いますが、直近で試そうとした場合の注意点として、メモを残しておきたいと思います。

Share

Written by Masayuki.Ozawa

9月 3rd, 2017 at 5:24 pm

Leave a Reply