小ネタ: Watson OpenScaleのInternalDBの中身を見る


:triangular_flag_on_post: (2019/2) Watson OpenScaleは**Watson OpenScale**に名前が変わりました

# はじめに
こんにちわ！石田です。年初からニッチな話題で恐縮です。

「説明可能なAI」の運用を支援する[Watson OpenScale](https://www.ibm.com/cloud/ai-openscale)はペイロードや構成情報を記録するためにRDBを使いますが、Liteプランなどのお試し環境用に小規模な「Free Lite Plan Database( Internal DB)」を選択できます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/50ce0c80-a1fb-dc93-ddb1-ca58844199d4.png)


これ、実体はクラウド上の(Compose) PostgreSQLなのですが、素だと接続情報が無く、中身を見ることができません。中身が見られると問題判別やお勉強にとても便利なので、以下その方法をご紹介します。

基本的には以下の2段階の流れになります
1. Watson OpenScaleのプライベートAPIを使ってDBへの接続情報(ホスト、ポート、DB名など)を入手する
2. ご自身のPCに[pgAdmin](https://www.pgadmin.org/)をインストールし[^1]、入手した情報を使って接続する

:triangular_flag_on_post: 　Watson OpenScaleのザクッと紹介は[こちらの記事](https://qiita.com/ishida330/items/ced6e5233ca61ae0af9d)などご参照ください


# 1. DB接続情報の入手
[Watson OpenScaleのプライベートAPI](https://aiopenscale-api.mybluemix.net/#/Configuration_(Private_API)) GET v1/data_marts/{data_mart_id}でDBの構成情報が入手できます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/f0b34412-78ab-d577-579e-ead20197f925.png)

- :warning:  非公開のプライベートAPIなので先々変更になる可能性があります
- 当APIを使うためにはIAMのapikeyからBearerトークンを生成のうえ、指定する必要があります
- REST APIなのでクライアントの言語は問いません
 

以下はPythonのサンプルです。ご自身の環境にあわせ変数 aios_env のコンスタント3箇所を変えれば動くはずです。

:warning:(2019/02/14) WOSのインスタンスの作成時期によってはJSONレスポンスのレイアウトが変わっていることがあるようです。最後のところで
`return response['database_configuration']['credentials']['uri']`でうまくとれない場合は、コメントアウトしてある`return response['database_configuration']['credentials']['connection']['postgres']['composed'][0]`のほうを試してみてください。（まあresponse全体をprintすれば設定すべき項目はわかりますけど)

```py
#  Watson OpenScaleのinternalDBの接続情報の入手
import requests, json

# IAM Tokenの入手
def getToken(apikey):
    url = 'https://iam.bluemix.net/identity/token'
    header = {'Content-Type': 'application/x-www-form-urlencoded', 
        'Accept': 'application/json'}
    payload = {'grant_type': 'urn:ibm:params:oauth:grant-type:apikey', 
        'apikey': apikey}
    response = requests.post(url, payload, headers=header).json()
    return response['access_token']


def getDBInfo():

    ##  CHANGE ME
    ##  platform_apikey ... IBM Cloudの 管理 - セキュリティ - プラットフォームAPIキー より作成
    ##  data_mart_id    ... AIOSの構成パネルより
    ##  subscription_id ... AIOSの構成パネルより
    aios_env ={
            "url": "https://api.aiopenscale.cloud.ibm.com",
            "platform_apikey": "XXXXYZfUMvhO_djAV0LFKfGF-XliEJTDMhlouU8-q-64",
            "data_mart_id"   : "XXXXf3e5-5538-43ce-862b-fc4a3cc90418",
            "subscription_id": "XXXX15fd-d229-4ab7-8cd5-e26bd1eadaf3"
    }

    aios_url = aios_env['url']+'/v1/data_marts/'+aios_env['data_mart_id']
    header = {'Content-Type': 'application/json', 
        'Authorization': 'Bearer ' + getToken(aios_env['platform_apikey'])}
    payload = {'subscription_id': aios_env['subscription_id']}
    response = requests.get(aios_url, payload, headers=header).json()
    return response['database_configuration']['credentials']['uri']
    # 新しいインスタンスではこちらのレイアウトの場合も
    # return response['database_configuration']['credentials']['connection']['postgres']['composed'][0]

print(getDBInfo())
# --> postgres://admin:XXXXXXXXJKAYMKLJ@sl-us-south-1-portal.31.dblayer.com:65382/compose
```

# 2. pgAdminでの接続

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/2def5e02-dc5e-838e-9ccc-18609ad3fccb.png)

上記のような接続情報の文字列が入手できたら、あとはご自身のPCに [pgAdmin](https://www.pgadmin.org/)[^1]をインストールし、接続情報をセットするだけです。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/b51e2745-fe48-3c11-5b2c-a154063eed02.png)

上記のように所定のスキーマの下にPayload、Feedback、Explainなどのテーブルがあり、中身を見られます。うまくいかない場合のエラーなども記録されているので問題判別に役立ちます。

例えば「ちゃんとWatson OpenScaleがスコアリングの要求を取れているのかな？」と思ったらPayloadテーブルの中身を見ればいいです。

なおinternal databaseはインスタンス毎に１つです。AIOSでは１インスタンスで複数のモデルを構成できますが、これらはSubscription IDで区別されています。（よって名前も **Payload_サブスクリプションid ** の形で場合によっては複数あります)

参考) Watson OpenScaleは[REST API](https://console.bluemix.net/apidocs/ai-openscale)や[Python Client](http://ai-openscale-python-client.mybluemix.net/)を提供しており、問題判別時の情報収集にはこれらを使って情報を入手してもいいのですが、多くはテーブルの情報を基にしているので、テーブルを直接見てしまったほうが早いかな、と思いまして..

# (2019/2/8追記) 3. SQuirreL SQL Clientもいいですね

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/37284dfe-a05f-96fb-6a8a-e57a6716cae9.png)

私の環境(Windows)だけかもしれませんが、なぜかpgadminは長く使ってるとハングしたりします。ちょっと操作のモッサリ感もあり。で、Javaベースの[SQuirreL SQL Client](http://squirrel-sql.sourceforge.net/)も試したんですが、こっちのほうが僕には快適でした。

- [PosgreSQLのjdbcドライバーを入手](https://jdbc.postgresql.org/)する必要があります
- あとはツール起動して１．で入手したDB情報にてjdbc文字列を指定すれば普通につながりました
- 接続の最初だけメタデータを大量に取ってるのでしょうか、数十秒かかりますが、その後は快適です。
- SQuirreL SQL Clientはデフォでは行を100行しかfetchしませんが、接続した後、上記で設定を変更できます
- 「接続」のプロパティで使うメタデータを絞ったりキャッシュを活用して接続の待ち時間を減らすこともできます。（僕は基本テーブル見るだけ、なのでそれ以外はいらない、としています）

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/36889a25-9890-c7c2-f177-1e3849d47a63.png)

[^1]: いわずもがな、でしょうがDBツールはpgAdminでなくてもかまいません。

以上です！