日本アイ・ビー・エム株式会社が毎月開催しているIBM Powerユーザーのための自由な語り場「IBM Power Salon」(月1回、第二水曜日の朝9時から開催)をご存じでしょうか?
https://www.ibm.com/blogs/systems/jp-ja/ibm-power-salon/
2022年12月14日に開催された第13回の、株式会社 松沢書店様による「IBM i エンジニア不在でもDXはできる」では、既存IBM i環境を見事に活用し、DXを実現された素晴らしい事例が披露されました。
https://video.ibm.com/recorded/132400405
とはいえ、1時間の講演時間では語りきれなかった詳細は、きっと他のIBM i ユーザーの方にも参考になるはず!ということで、松沢書店 システム部部長の山口様に課題解決の方法について具体的にご説明いただきます。
第4回目の今回はCSVファイルをIBM i にアップロードする際の細々とした準備作業を簡単にしてくれるAPIを、オープンソースのAPI開発プラットフォームである「Insomnia」を活用して作ってみます。ソースもGitHubに公開されていますので、同じお悩みを持つ方必見の内容です!
第4回:API(Python)を作ってIBM iにCSVをアップロード
株式会社松沢書店
システム部
山口昌一
目的と経緯
IBM i を使用していてこんなケースはないでしょうか?「このエクセルに500種類の商品データがあるんだけど、その商品の売上データを出して欲しい。」
そんな時、やり方は様々かもしれませんが、受け入れるファイルを定義したり、似た感じのファイルをQRYで作って受け入れ準備したり、そのうえエクセルからCSVにしたファイルを確認して、ダブルクォーテーションが必要な所は付けていったりと、割と時間がかかる作業になってしまいます。
IBM i でなくてもこういった大量データの絞り込みには一工夫必要かと思います。
今回はこういう意外と大変な作業を、とても簡単にするAPIを作成していきます。
1. 概要図

▲図1. 弊社環境です。WEB部分は今回は作りません。Insomniaで代用します。

▲図2. 今回作成するものです。WEBのところがフリーソフトInsomniaに変わります。
2. 弊社環境詳細説明
弊社で実際に使用しているAPIの機能をご紹介し、その中のAPI部分の作り方、使い方をご説明いたします。APIを叩く時はWEBの代わりに「Insomina」というアプリを使いますのでそのインストール方法、使用方法もご説明いたします。
これらのソースはすべてGitHubにアップしておりますので、GitHubからのダウンロード方法などもご説明いたします。
まず、弊社で利用しているCSVアップローダーは以下のような動きをします。

1.WEB上に左画面のアップローダーがあります。
アップしたいCSVをドラッグドロップします。

2. ドラッグ&ドロップすると、プレビューが表示されます。ここで各列を数値にするか文字列にするかを決めていきます。
ヘッダ行も選べますので任意のヘッダ行にしておきます。

3. IBM i のライブラリ/ファイルを指定します。
(弊社はいくつか登録があり選択出来る様にしております。)

4. 「AS400にUpload」をクリックします。少し待ちます。

5. Alertが出てアップロードされます。

6. IBM i を確認してみます。ちゃんとアップされたことがわかります。
環境
-API-
- Python3.8.6
- Windows11
- Visual Studio Code
- Insomnia 2023.4.0
-WEB-
- React (今回は作成しません)
-GIT-
3. APIを作成

作るファイルは3つです。
CSVTOIBMI
├─ api.py CSVをPUTのリクエストで受けます。
├─ common.py IBM iのシフトインシフトアウトを考慮する関数等です。
└─ IBMiUploader.py IBM iにCSVの値をCREATE、INSEARTします。
おおまかな流れは以下の通りです。
- api.pyでInsomniaからのリクエストを受け付けます。
- IBMiUploader.pyでCSVの抜けや、データ型、文字列の最大長をチェックしていきます。
その中でcommon.py内の関数を使い全角や半角が混じった時の正しい文字列の最大長を取得します。 - 最後にIBMiUploader.pyでSQL文を作成しIBM i にINSERTします。
3-1.api.py ソースと解説
全ソースは以下で取得できますのでご参照下さい。
https://github.com/MzSysoprYama/csvToIBMi

コメントには記載がありますが簡単に解説しておきます。
flaskとjsonをインポートします。
flaskはpythonのWebアプリケーションフレームワークでこれを使ってWEBサーバーを作ります。

ここで/IBMiUploaderにPUTリクエストが来たら実行するよ、という指定です。

最後のapp.runだけでサーバーがport3001でlistenしてくれます。

上記はInsomniaから渡されるパラメータになります。
1. | file | csvファイル |
2. | tableName | IBM i の「ライブラリ.ファイル名」 |
3. | startRow | ヘッダが有る行です。このプログラムはヘッダありのCSVになります。 |
4. | columnTypes |
列のデータ型になります。 例えば1列目文字列、2列目数値の場合は 「string,number」という風に「,」で区切ります。 型の指定はこの2種のみです。 |

上記はこの後作る「IBMiUploader」の処理になります。ちゃんとINSERTされれば「success」が返ってきます。その他エラーの場合は「fail」になります。
3-2.IBMiUploader ソースと解説
画面の幅の都合上折り返している箇所がございますがご了承ください。全ソースは以下で取得下さい。
https://github.com/MzSysoprYama/csvToIBMi

重要部分の解説になります。他コメントをご参照ください。

DATA_SOURCE_NAMEはこのあと説明するODBCで設定したDSNにします。
UID、PIDはIBM i にログインするユーザー、パスを入れて下さい。
このアプリはODBCで接続をしておりますので、ODBCの設定が必要になります。
まずこのアプリ用のODBCデータソースを作成下さい。弊社では「MTZAPI」で作成したので上記が「MTZAPI」になっております。


ライブラリリストは当アプリで使用したいライブラリを指定してください。
※注意点です。
トランザクションを使用していない場合は

「サーバー」タブの下「拡張」からコミット・モードを「即時コミット(*NONE)」に変更してください。
これを行わないとINSERT、CREATEが出来ません。

ログは上記の設定をするだけでfilenameの場所にlogを書き込んでくれます。かなり楽ちんなので使います。


上記を見て頂ければわかる様に、このプログラムはCSVの行数や、各列の文字のlengthを確認してSQL文を生成し、CREATEして行数文INSERTしているだけです。
CREATEもいきなりしますので、ライブラリさえ作っておけばレコード様式を定義する必要はございません。アプリがよしなに実行してくれます。
3-3. Common.py ソースと解説
全ソースは以下で取得下さい。
https://github.com/MzSysoprYama/csvToIBMi

こちらのファイルで重要な箇所は、例えば「松沢書店001山口」の様な全角半角込みの文字データがあった際に、シフトインシフトアウト込みの文字のlengthを取る必要があり、その処理が前半になります。
詳細はコメントにてご確認下さい。
4. Insomniaを使ってファイルをIBM i に取り込む
https://insomnia.rest/から
「get started for free」で無料版を入手してください。
Insomniaを開いたら

赤丸部分を入力していきます。
メソッドはPUTを選択し
URLは「http://localhost:3001/IBMiUploader」を指定します。
fileは任意のCSVファイルを用意ください。画面に合わせる場合は、2列のCSVで下図の様なデータをご用意ください。data.csvとあるところをクリックするとエクスプローラーから選択可能です。

table.NameはIBM iのライブラリとファイル名になります。この場合は
MTZAPI.YAMAGUC
なのでライブラリ「MTZAPI」
ファイル名「YAMAGUC」になります。ファイルが存在しない場合はここで指定した名前で新規作成されます。
startRowはヘッダ行になります。基本的に「1」で問題ございません。
columnTypesは上図は2列で数値、文字で並んでいますので「number,string」と入力下さい。
列が増えたらその分増やしていってください。
全て入力が済んだらまず、作成した「api.py」を実行します。
python api.py

Insomniaに戻り

ボタンをクリックしてください。

問題なければ”success”が返ってきます。

IBM i でも確認します。
ちゃんとファイルが出来ています。
あとがき
今回は、IBM i は便利だし速いしでもちょっと面倒なところもあるよ、という事例の解決策になります。弊社では入力用のWEB画面を作っておりますが、今は「Insomnia」の他にも「postmnan」「API TESTER」などリクエストを発行できるアプリは沢山でております。APIを作ってしまえば呼ぶ側はいろんな選択肢から選べます。
実際これだけGitHubからダウンロードして、「Insomnia」を使えばCSVのアップローダとしては十分機能します。わざわざ画面を作る手間も省けますので、コードを打つのは面倒だなという方は以下の方法でGitHubからダウンロードして試してみて下さい。
https://github.com/MzSysoprYama/csvToIBMi

上記クリック

ZIPで落として解凍して下さい。
次回は「社内に沢山あるDBをリンクテーブルでまとめよう」になります。