##はじめに
クラウドサービスといえばAWSのようなイメージがあったのですが、IBMも"IBM Cloud"としてサービスを提供しています。
調べてみると、IBM Cloudにも多くのサービスが提供されており、いくつかのサービスは無料で使えるとのこと。
特に、代表的なIBM製RDBMS"DB2"を200MB以下であれば無料で使える(2020/07時点)、というのはかなり大きいのではないかなと。個人で色々やるなら、200MBもあれば十分でしょう。
同じく、一定量のリクエスト以下なら無料で使える"IBM Cloud Funtions"と連携して、Db2 on Cloud上のテーブル参照/更新ができるようになるまでを記載してみました。
##やったこと
①DB2サービスを作ってみる
IBM Cloudのアカウント作成後からスタートです。
IBM Cloudログイン画面
検索ボックスにdb2と入力して、db2のサービス画面を開きます。
リージョンはロンドンかダラス、料金プランはLiteを選択します。この2つ以外のリージョンではLiteプランが無いので注意です。
右下の作成ボタンで、db2サービスが作られます
db2サービスが作成されました。
テーブルとかを作る前に、資格情報を作成しておきます。Cloud Functionからデータベースへ接続する際に必要となります。
左のメニューから"サービス資格情報"を開きます。
db2サービスを作った直後は、資格情報が何も無い状態だと思います。
①"資格情報作成"ボタンを押します。名称の入力を求められるので、何かしら入力します。
②資格情報が作成されるので、名称の左側の"V"みたいな部分を押して情報を開きます。
③"ssldsn"で始まる部分が接続に必要となるため、控えておきます。
資格情報を作成したら、db2のコンソールを開きます。
左メニューから"管理"を選択し、"Open Console"ボタンを押します。
db2サービスが作られたので、テーブルを作ります。今回は事前に用意したcsvファイルを読み込ませることで、テーブルを作成することとします。
左上の緑色三本線のアイコンをクリックし、LOAD→Load Dataの順に開きます。
今回は、以下のようなcsvファイルを使うこととします。
NUMBER,NAME,UPDATE_TIME
1,Taro,2020-01-01 18:00:00
2,Hanako,2020-02-03 21:00:00
3,Mike,2020-02-14 14:30:00
真ん中あたりの"File Selection"に、対象のcsvファイルをドラッグアンドドロップします。
ファイルをアップロードしたら、右下の"Next"ボタンで先に進みます。
スキーマー/テーブルを選択する画面となります。今回は既存のスキーマーで、新規にテーブルを作成する形にします。
Schemaは、"AUDIT"や"DB2INST1"みたいなシステムチックな名称のスキーマーとは別に、英語3文字+数字5桁のスキーマーがあると思うので、それを選択します。
次のTableは、右上の"New Table"をクリックします。
Create a New Tableでは、テーブル名を入力して、"Create"ボタンをクリックします。
最後に右下の"Next"ボタンを押すと、次の画面に進みます。
列名などを設定する画面となります。
今回はそのまま、右下の"Next"ボタンで次に進みます。
ロードが実行されるまで、少し待ちます。
ロード完了後、"View Table"ボタンで、ロードしたテーブルを確認することができます。
円グラフでLoadに成功/失敗したレコードの割合が確認できるようです。
以上で、Db2側のセットアップ/テーブル作成は完了です。
SELECTするFunctionを作ってみる
続いて、pythonを実行するためのCloud Functions(アクション)を準備します。
IBM Cloudのトップページに戻り、検索ボックスにfunctionと入力し、"Functions"を開きます。
アクション名を入力します。
今回はpythonでコーディングするので、ランタイムは"Python 3.7"を選択して、"作成"ボタンを押します。
コーディングの画面となりました。
デフォルトで用意されているmain関数の中に記述した処理が、アクションを起動することで実行されるようです。
main関数の中に、pythonで処理を書いていきます。
今回は下記のような、テストテーブルから特定の行を取得するコードにしました。最低限、動くための処理のみを記載しているので、実際に運用していく処理を記述する際にはエラー処理や処理状況のログ出力などがあったほうが良いと思います。
import sys
import ibm_db
def main(dict):
# 資格情報の内容をssldsn変数に代入する
# "ssldsn":"DATABASE=XXXXX;HOSTNAME=XXXXX;PORT=XXXXX;PROTOCOL=TCPIP;UID=XXXXX;PWD=XXXXX;Security=SSL;"
ssldsn = "DATABASE=XXXXX;HOSTNAME=XXXXX;PORT=XXXXX;PROTOCOL=TCPIP;UID=XXXXX;PWD=XXXXX;Security=SSL;"
#DB接続
db_conn = ibm_db.connect(ssldsn,"","")
#SQLの組み立て
sql = "SELECT * FROM TEST_TABLE WHERE NUMBER = ?"
db_stmt = ibm_db.prepare(db_conn,sql)
number = 3
ibm_db.bind_param(db_stmt,1,number)
#SQLの実行
ibm_db.execute(db_stmt)
row = ibm_db.fetch_tuple(db_stmt)
#DBの切断
ibm_db.close(db_conn)
return {'name' : row[1] }
保存できたら、同じ位置に"起動"ボタンが表示されます。
押すと記述したコードが実行されて、処理結果が表示されます。
実行する際に覚えておくと良いのが、Functionsの課金額は(使用したメモリーサイズ)×(使用した累計秒数)で計算されます(2020/07時点、400,000GB分は無料枠として使えます)。
なので、お試しで使う際は使用するメモリーサイズは小さくしておくほうが良いです。左側のメニューの"ランタイム"から、使用するメモリーサイズを変更することができます。
INSERTするFunction(引数あり)を作ってみる
次はテスト用テーブルに行を追加するFunctions(アクション)を作ってみます。その際、"NAME"列の値はアクション実行時の引数から取得するようにしてみます。また、"UPDATE_TIME"列にはアクション実行時の時刻が入るようにします。
前のセクションと同じ流れで、Funtionsで新規アクションを作成します。今回は"insert_test"という名前にしました。
コード内容は下記の通りです。
import sys
import ibm_db
import datetime
def main(dict):
# 資格情報の内容をコピペ
ssldsn = "DATABASE=XXXXX;HOSTNAME=XXXXX;PORT=XXXXX;PROTOCOL=TCPIP;UID=XXXXX;PWD=XXXXX;Security=SSL;"
#DB接続
db_conn = ibm_db.connect(ssldsn,"","")
#SQL文の組み立て
sql = "INSERT INTO TEST_TABLE VALUES(?,?,?)"
db_stmt = ibm_db.prepare(db_conn,sql)
id = 5
name = dict['name']
update_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
ibm_db.bind_param(db_stmt,1,id)
ibm_db.bind_param(db_stmt,2,name)
ibm_db.bind_param(db_stmt,3,update_time)
#SQL文の実行
rtn = ibm_db.execute(db_stmt)
#DB切断
rc = ibm_db.close(db_conn)
return { 'return-code': rtn }
引数を指定してアクションを実行するには、"起動"ボタンの左にある"パラメータを付けて起動"ボタンをクリックします。
下記のようなポップアップが表示されるので、引数情報をjson形式で記載します。記載した内容がmain関数の引数dictに格納されます。
今回、dictから'name'というキーで'Jiro'という値を取得するようにしたいので、
{ 'name' : 'Jiro'}
と入力して、"適用"ボタンを押します。
あとは、"起動"ボタンを押してアクションを実行します。
テスト用テーブルに正しく行が追加されていることを確認しておきます。
Db2コンソールを開き、左上の緑色三本線のアイコンをクリックし、RUN SQLを開きます。
SQL記述用のコンソールが開きます。ここにSQLを記述して左下の"Run all"を押すとSQL文が実行されます。
今回はテストテーブルの中身を確認したいため、
SELECT * FROM TEST_TABLE;
のSQLを実行してみたところ、Nameが'Jiro'の行が追加されているのが確認できました。
終わりに
IBM Cloudを始めたばかりで、Liteアカウントでもこうやって動くものを作れるみたいです。クラウド環境のサーバーレス処理の体験にぴったりと思います。
今後、トリガー(時刻到来/ファイルのアップロード)でアクションを実行したり、処理結果を別のサービスに渡せるように拡張していきたいです。