SPSS Modelerの外部ローダーを使う（Db2編)

SPSS Modelerでテーブルに書き出す際に、通常はSQLのINSERT文が使われます。INSERTは特にカラム表に対して非常に遅いため、LOADコマンドを使いたいことがあります。

SPSS ModelerのDBエクスポートノードには外部ローダーという機能があり、これを使うとLOADコマンドでDBに書き出すことができます。
この記事ではDb2を例にその使い方を解説します。

* テスト環境
    * Modeler 18.4
    * Python 3.8.10
    * Windows 11 64bit
    * Db2 Warehouse on cloud

＊サンプルストリーム

https://github.com/hkwd/spsssample/raw/master/221115externalloader/exloader.str

# 構成図
以下のような構成のイメージになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1bb3a0ed-1701-0cdc-358b-6f55cd272b7d.png)

# ①Db2 Runtime Clientの導入

まず、Db2のRuntime Clientを導入する必要があります。Db2のクライアントにはIBM Data Server Driver for ODBC and CLI (64-bit)などいくつの種類かありますが、Runtime Clientを選んでください。

#### Db2 11.5ランタイムクライアントのインストール on Windows - Qiita 

https://qiita.com/kawada2017/items/6657ccc996c1f1d3706d

# ②Pythonの導入

Modeler 18.4でサポートされているPythonは3.8ですので、Python 3.8を導入します。

https://www.ibm.com/software/reports/compatibility/clarity-reports/report/html/softwareReqsForProduct?deliverableId=0E1C00D07E5C11EC93C02AA4DE91E682&osPlatforms=Linux|Mac%20OS|Windows&duComponentIds=D001|S002&mandatoryCapIds=13&optionalCapIds=7|47|22|72|186|223#!


Python Release Python 3.8.10 | Python.org 

https://www.python.org/downloads/release/python-3810/


# ③options.cfgの修正
C:\Program Files\IBM\SPSS\Modeler\18.4\configにある
options.cfgの「python_exe_path」に、前の手順で導入したpythonのexeのパスを記述します。

```:options.cfg
python_exe_path, "C:/Users/xxxxxxx/AppData/Local/Programs/Python/Python38/python.exe"
```

# ④db2load.pyの修正
Db2の外部ローダーの実体は、C:\Program Files\IBM\SPSS\Modeler\18.4\scriptsにある
db2load.pyというpythonスクリプトです。

まず、今回は日本語WindowsのShift JIS環境で外部ローダーを動かし、ターゲットのDb2はUnicodeですので、44行目の
```:db2load.py修正前
codepage = ''
```
を
```:db2load.py修正後
codepage = '943'
```
に修正してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0e5bff7c-a555-e74c-1ea5-48484e680c25.png)

また、Modeler 18.4とPython 3.8.10の組み合わせだと以下のエラーとなり動きませんでした（ログファイルexloder.log_Serverに出力されていました）。

```
Traceback (most recent call last):
  File "C:\Program Files\IBM\SPSS\Modeler\18.4\scripts\db2_loader.py", line 244, in <module>
    write_control(dom, controlfile)
  File "C:\Program Files\IBM\SPSS\Modeler\18.4\scripts\db2_loader.py", line 155, in write_control
    outfile = open(filename, 'w')
TypeError: expected str, bytes or os.PathLike object, not _TemporaryFileWrapper
```

そのため、242行目の
```:db2load.py修正前
controlfile = TemporaryFile()
```
を
```:db2load.py修正後
controlfile = TemporaryFile().name
```
に修正してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/36618627-8db5-9610-da3d-c3c6e71e363e.png)




# 実行テスト

以下のようなデータをロードしてみます。日本語も含まれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4d971fc4-9ce6-8889-b200-b6e3ce870fc8.png)

「DBエクスポート」ノードを接続し、データソースとテーブル名を設定し、「詳細」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b8326c1d-97a3-182a-947d-48bebb1f8b60.png)

「外部ローダー経由」にチェックを付けます。
また、「ログの生成」もチェックをつけ、出力しておくことをお勧めします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e4555239-26d7-3580-6984-17e7e898d146.png)

実行をするとModelerのメッセージにはCREATE TABLEは記録されますが、INSERTは行われていません。ただ、LOADもSQL文ではないのでメッセージには記録されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/78019a0c-c747-7ab7-4ba2-36c829d423eb.png)

「詳細オプション」で指定していたexloder.logを確認すると以下のようにLOADが成功したことがわかります。

```:exloder.log
   データベース接続情報
 データベース・サーバー = DB2/LINUXX8664 11.5.7.0
 SQL 許可 ID            = HKWD
 ローカル・データベース別名 = BLUDB

SQL3109N  ユーティリティーが、ファイル
"C:\temp\MODELE~1\A490-6F44-8911-8-bulkload-1.txt"
からデータのロードを開始しています。
SQL3500W  ユーティリティーが "11/15/2022 10:09:43.517345" に "ANALYZE"
フェーズを開始しています。
SQL3519W  ロード整合点が開始されました。 入力レコード・カウント = "0"
SQL3520W  ロード整合点が成功しました。
SQL3515W  ユーティリティーは、"11/15/2022 10:09:44.315208" に "ANALYZE"
フェーズを完了しました。
SQL3500W  ユーティリティーが "11/15/2022 10:09:44.334084" に "LOAD"
フェーズを開始しています。
SQL3110N  ユーティリティーが処理を完了しました。  "1"
行が、入力ファイルから読み取られました。
SQL3519W  ロード整合点が開始されました。 入力レコード・カウント = "1"
SQL3520W  ロード整合点が成功しました。
SQL3515W  ユーティリティーは、"11/15/2022 10:09:44.771839" に "LOAD"
フェーズを完了しました。
SQL3500W  ユーティリティーが "11/15/2022 10:09:44.813769" に "BUILD"
フェーズを開始しています。
SQL3213I  索引付けモードは "REBUILD" です。
SQL3515W  ユーティリティーは、"11/15/2022 10:09:45.563931" に "BUILD"
フェーズを完了しました。

読み込まれた行数        = 1
スキップされた行数      = 0
ロードされた行数        = 1
拒否された行数          = 0
削除された行数          = 0
コミットされた行数      = 1
```

また、「exloder.log」と同じディレクトリの「exloder.log_Server」というファイルに実行したpythonのコマンドも記録されています。
```:exloder.log_Server
Execute Command: "C:\Users\xxxxxx\AppData\Local\Programs\Python\Python38\python.exe" 
"C:\Program Files\IBM\SPSS\Modeler\18.4\scripts\db2_loader.py" 
C:\temp\MODELE~1\A490-6F44-8911-8-2.bin 
C:\temp\MODELE~1\A490-6F44-8911-8-bulkload-1.txt 
"" BLUDB "hkwd " "xxxxxxxx " DATATYPETEST "" C:\temp\exloder.log 1
```

データは以下のように正しくLOADされていました。日本語も正しく入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/49b066db-80ec-bb49-93a8-74f7ae77b3c3.png)

### 参考:SPSS Modeler外部ローダーのアーキテクチャーとスクリプトの中身 - Qiita 
https://qiita.com/kawada2017/items/6fc8649594c63bed57f0