SE の雑記

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

SQL Server 2017 CTP 2.1 の Python の ML サービスで日本語データをインプットデータとして渡す際の覚書

one comment

今回の前提としては、データベースの照合順序に「Japanese_XJIS_140_CI_AS」を使用している環境となります。

このデータベースに対して、以下のようなデータを登録します。

DROP TABLE IF EXISTS T1
CREATE TABLE T1 (C1 varchar(2), C2 nvarchar(1))
INSERT INTO T1 VALUES('あ', N'あ')
SELECT * FROM T1


これに対して、以下のようなインプットをアウトプットとして返す、シンプルな Python スクリプトの実行を行ってみます。

 EXEC sp_execute_external_script
 @language =N'Python',
 @script=N'OutputDataSet = InputDataSet',
 @input_data_1 = N'SELECT C1, C2 FROM T1'
 WITH RESULT SETS((C1 varchar(2), C2 nvarchar(1)))

 
そうすると、以下のようなエラーが発生するかと。

メッセージ 39004、レベル 16、状態 20、行 1

‘sp_execute_external_script’ に HRESULT 0x80004004 を指定して実行中に、’Python’ スクリプト エラーが発生しました。

メッセージ 39019、レベル 16、状態 2、行 1

外部スクリプトエラーが発生しました:

Traceback (most recent call last):

  File "<string>", line 2, in <module>

  File "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 522, in rx_sql_satellite_pool_call

    exec(inputfile.read())

  File "<string>", line 3, in <module>

  File "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 474, in rx_sql_satellite_call

    rx_native_call("SqlSatelliteCall", params)

  File "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy\RxSerializable.py", line 19, in rx_native_call

    ret = px_call(functionname, params)

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0x82 in position 0: invalid start byte
Invalid BXL stream
外部スクリプトからの STDOUT メッセージ:

C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy

Python へのデータの連携ですが、全角文字 (ダブルバイト / マルチバイト文字) については、Unicode データ型で連携が必要となるようです。
半角文字のみを含んでいる場合は、varchar / char を使っていて問題ないのですが、全角文字を含んでいるようなデータを登録している場合は、単純に非 Unicode 文字列を、インプットのデータストリームとして渡してしまうとエラーになるようです。
先ほどのクエリであれば、以下のような修正が必要なようですね。。

 EXEC sp_execute_external_script
 @language =N'Python',
 @script=N'OutputDataSet = InputDataSet',
 @input_data_1 = N'SELECT CAST(C1 AS nvarchar(2)) AS C1, C2 FROM T1'
 WITH RESULT SETS((C1 varchar(2), C2 nvarchar(1)))

 
データの文字列型を nvarchar / nchar で構成していれば問題はないのですが、そうでない場合、明示的にキャストをしてインプットデータとして渡しておく必要がありそうです。
これであれば、問題なく実行することができました。
image
英数の全角の場合、英語の照合順序を使用すると半角で登録されるようなケースもあるようで、テストについては、英数ではなく、漢字やかなを使って実施しておいた方がよさそうな感じもありました。

アウトプットのデータストリームに、日本語の文字列を返すことはできそうだったのですが、SQL Server の Python スクリプトの標準出力に日本語を出力しようとしても文字化けするようでしたので、SQL Server のスクリプト内でのデバックには少し気を付けておいた方がよさそうではありました。
文字コードがらみは面倒ですねぇ…。

Share

Written by Masayuki.Ozawa

7月 1st, 2017 at 9:49 pm

Posted in SQL Server

Tagged with , ,

One Response to 'SQL Server 2017 CTP 2.1 の Python の ML サービスで日本語データをインプットデータとして渡す際の覚書'

Subscribe to comments with RSS or TrackBack to 'SQL Server 2017 CTP 2.1 の Python の ML サービスで日本語データをインプットデータとして渡す際の覚書'.

  1. Nice catch! will add this to the docs.

    Jeannine Takaki

    6 9月 17 at 11:23

Leave a Reply