Watson QueryでIBM Object Storage上のCSVファイルを仮想化する

[Watson Query](https://cloud.ibm.com/catalog/services/watson-query)は、データの物理的なフォーマットや場所を理解する必要がなく、データを移動させることなくアクセス、操作(=[データ仮想化](https://qiita.com/nishikyon/items/ef2d60b4687b8a6c3e39#1-%E3%83%87%E3%83%BC%E3%82%BF%E4%BB%AE%E6%83%B3%E5%8C%96))、分析を可能にするIBMCloudのSaaSのサービスです。
以前の名前はData Virtualizationとなっていましたが、この名前はSW版のみの名前となり、SaaS版は**Watson Query**という名前になりました。
この名前の変更と同時に、Liteプランが登場し、作成してから1ヶ月で削除されてしまうのですが、無料で使えるようになりました。

Watson Queryのサービス作成方法は、@Shumpei_Kuboさんのこちらの記事「[データ仮想化機能である Watson Query を有効化する。](https://qiita.com/Shumpei_Kubo/items/1ff4f6d98de1435ce458)」 を参考に作成してみてください。

この記事はWatson QueryでIBM Object Storage(ICOS)上のCSVファイルを仮想化する手順を説明します。GUIなど変更が頻繁ですが、この情報は2022/01/28時点の情報です。

参考: [Virtualizing data with Watson Query](https://dataplatform.cloud.ibm.com/docs/content/dvaas/virtualizing_data.html?context=cpdaas&audience=wdp)

#1. IBM Object Storage(ICOS)にCSVファイルを準備

ちょっと説明が長いです・・・・

オブジェクトストレージからの仮想化はPARQUET（またはPARQUETFILE）、ORC（Optimized Row Columnar）、CSV（Comma Separated Values）、TSV（TAB Separated Values）、JSONデータ形式がサポートされています。

- CSVファイル、TSVファイルの場合、.csv、.tsvのファイル拡張子が必要です。
JSONファイルの場合、.jsonのファイル拡張子が必要です。
- PARQUET または PARQUETFILE の場合、ファイル拡張子は必要ありません。メタデータはデータファイルから抽出されます。
- ORCの場合、ファイル拡張子は必要ありません。メタデータはデータファイルから抽出されます。


Watson Queryで仮想化できるファイルには少々制約があります。以下は主な制約です。
(2022/01/25現在の情報)

- 引用符文字`'`, `"`を含むデータは使用できません。
- CSV、TSV、JSON 形式はUTF-8 文字エンコーディングのみがサポートされます。
- テーブルの最大列数は 2048列 までサポートしますが、表示は最大 1012 列までです。

そして、

- 仮想化対象ファイルはフォルダーの下にないといけない
    - フォルダーの概念はObectStorageには実はないので、ファイル名の前にスラッシュで区切られた文字列がフォルダとして認識されます。
        - OK: folder1/file1.csv
        - NG: file1.csv
        
- 1つのフォルダーの中の全てのcsvが仮想化対象、
    - 1つのフォルダー複数ファイルがあれば、それは全て1つの仮想化テーブルにデータが入る
    - つまり**ファイルを1つ1つ別々に仮想化したければ、別々のフォルダに入れる**

もうフォルダ名を考えるのも面倒な制約な気がしますが、迷ったらICOS上のファイル名は
`ファイル名/ファイル名`
みたいにスラッシュで重ねてしまえば、わかりやすいし（？）よいかと思います。
例: `TEST.CSV`をICOS上では`TESTCSV/TEST.CSV`として保存

すでにフォルダなしでICOS保存済みのファイルはコピーして名前を変えてしまえばよいです。
ただコピーはIBM CloudのGUIではできない、かつ同じファイル名はオブジェクトのプレフィックスでフォルダ名を入れてもアップロードできないので、以下に記載のにpythonのコードで簡単にコピーして名前も指定し、やってみてください。
[IBM Cloud Object Storage (ICOS) をpythonから操作](https://qiita.com/nishikyon/items/5cf4eaaea380bb0db1df)の　[5. ファイルのコピー](https://qiita.com/nishikyon/items/5cf4eaaea380bb0db1df#5-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%B3%E3%83%94%E3%83%BC)

まとめると
準備としては**フォルダー付きのCSVファイル**をICOSのどこかのBucketに入れておいてください。
`TEST.CSV/TEST.CSV` みたいな感じです。（特にファイル名と同じフォルダ名が必須というわけではないです）

#2. IBM Object Storage上のCSVファイルを仮想化

いよいよ本題です！

参考：　[Creating a virtualized table from files in cloud object storage in Data Virtualization](https://www.ibm.com/docs/en/cloud-paks/cp-data/4.0?topic=objects-creating-virtualized-table-from-cloud-object-storage)

##2-1. データソースの追加
データソースはICOSバケットごとに一度登録すればよいです。毎回登録の必要はありません。
###1. 準備

ICOSの以下の情報を取得しておきます。尚資格情報はいろいろな組み合わせで設定可能なようにみえるのですが、2022/01/26現在は`Access Key`と　`Secret key`の組み合わせのみ設定可能でした(そのうち他も対応される？？？)。

- バケット名(パケット限定が必要な場合)
- [エンドポイント](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-endpoints)
- 操作するICOSの以下の資格情報
   - access_key_id
   - secret_access_key

資格情報を作成する際、access_key_idとsecret_access_keyを取得するため、詳細オプションから「HMAC資格情報を含める」をオンにして作成してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/2a19989e-3c6f-3832-1c15-413e6f053930.png)


取得方法は[IBM Cloud Object Storage (ICOS) をpythonから操作](https://qiita.com/nishikyon/items/5cf4eaaea380bb0db1df)の　[1.準備](https://qiita.com/nishikyon/items/5cf4eaaea380bb0db1df#1%E6%BA%96%E5%82%99)を参考にしてください。

access_key_idとsecret_access_keyはサービス資格情報の鍵名をクリックすると表示される
access_key_idとsecret_access_keyの値です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/f1c82eee-0ee4-c980-6d83-768f89e004f8.png)




###2. メニューから「Data Virtualization」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/9af52237-c17f-6606-b2f1-3e5ffbfe227a.png)

###3. 「データーソース」の画面が表示されるので、「接続の追加」をクリック。
すでに接続したいICOSに対してプラットフォーム接続を作成済みの場合は、そこから選択できます。その場合は「既存の接続」をクリックして進めてください。
ここでは、「新しい接続」を作成するとして進めます。「新しい接続」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ee71f661-7259-4509-9960-4bf50ce229d5.png)

###4. 「Cloud Object Storage」をクリックし、「選択」をクリック
「Cloud Object Storage」が見つけにくいので、検索フィールドに`cloud`と入力すると絞られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e7b50e17-3abf-8e3e-d822-d0c716139ee2.png)

###5. 接続情報を記入

- 接続の概要
    - 名前：　適当な名前を入れる
    
- 接続の詳細
    - パケット：　アクセスするバケットを限定したい場合は、仮想化するファイルのあるバケット名（**必須ではないです**）
    - ログイン URL： エンドポイントを`https://`付きで記入
        - 例：　https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud
- 資格情報
    - Authentication method： `Access Key and Secret key`を選択
        - 2022/01/26現在は`Access Key`と　`Secret key`の組み合わせのみ保存可能でした。
    - アクセス・キー: 接続するICOSのaccess_key_id
    - 秘密鍵(アクセス・キーを入力すると入力欄が表示されます): 接続するICOSのsecret_access_key

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/6505286a-04d9-1403-4c52-24d1f3412512.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/90269632-16e6-e089-4580-f68ec9fa367a.png)



###6. 「接続のテスト」をクリックし接続をテスト
「テストは正常に終了しました。」の表示を確認。
エラーがあれば、情報を修正する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/5a28a36a-bf3d-a55d-be30-ebd7ca281d48.png)




###7.「作成」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/45ba6936-5229-7b2b-81b6-9f20574b7409.png)

作成が成功するとリストに表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/674558e8-89f0-59cd-5a26-b61a8bbfcf47.png)

##2-2. 仮想化
###1. 「データソース」の右の`V`をクリックして、「仮想化」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/8e20add0-cd49-28ff-fa00-ae46bb8564f3.png)


###2. 「ファイル」をクリックし、仮想したいファイルの入っているデータソースのエンドポイントの文字列をクリック。
最初はデフォルトで「表」なので、「ファイル」をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/264f6074-4c45-4e8a-5c71-14716427eaaa.png)



###3. バケット名をクリック
バケット名がデータソースに設定されている場合はを最初から表示済み。
バケット名がデータソースに設定されてない場合は、バケット名を「パケット」の入力欄に入力すると表示されます。ワイルドカード指定機能などないので、一字一句正しいバケット名を入れる必要があります(自動的にバケット名の候補を全部出してくれるとか、そういう親切機能は現状ありませんでした）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e1b89f9f-60bb-835d-40f8-c1f11e83485c.png)



###3. フォルダー名をクリック
パケット直下のTEST_1.CSVは残念ながら仮想化できません。一見中身も見えてできそうなんですが、、、、。2022/01/26現在はあくまでもフォルダー単位です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a6dde2e4-4621-886c-f7fa-5de55913e438.png)


仮想化したいファイルが入っているフォルダの目玉マークをクリックすると、フォルダー内の最初のファイルをプレビューすることができます。 ここからでもカートに追加できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a76ef013-93c0-f4bc-4432-4e670c4be35c.png)


ここではカートに追加ぜずに、さらにフォルダーを開いてプレビューしてみます。
仮想化したいファイルが入っているフォルダーの目玉**以外の**エリア（下のイメージでは`>`）をクリックし、フォルダの中のファイル一覧を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/43958377-1130-80c8-d4ed-7da627712cef.png)


フォルダの中のファイル一覧を表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/806e7fee-9a20-0d18-c452-cc4de5e8e051.png)



###4. ファイルの中身をプレビューし、カートに追加
プレビューしたいファイル名をクリックし、必要に応じて「先頭行を列見出しに使用する」をONにし、問題なければ「カートに追加」をクリックします。
フォルダーに複数ファイルがある場合は、フォルダー内のすべてのファイルを 一つの表として仮想化されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/b275544d-6768-6ba4-3859-c0bd53d0d9f4.png)

###5. 「カートの表示」をクリックして、カートを表示します。
割り当て先(以下の例では「自分の仮想化データ」)、表名、スキーマ名をセット。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/432d68be-7236-f0b7-f3b3-768090a98038.png)


必要に応じて右端の︙をクリックし、「列の変更」や「プレビュー」を実施する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ae11a760-a00f-c56a-1e7f-4fc8354cf2f3.png)


###6. 設定完了したら「仮想化」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ab955099-7172-d857-9ea2-be9d58bbd075.png)

下記のメッセージが表示された場合は「Confirm」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/d2627036-fa5e-b88e-5d7a-dfc194f0398f.png)

仮想化が開始されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/0ad3b3af-6601-24e6-d7a8-d81cadb6782f.png)

ステータスに「完了」と表示されたら、仮想化完了です。
「自分の仮想化データを表示」をクリックして、確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/2ca6c4bd-39aa-b076-c3ba-e697388b3465.png)

####7. 「自分の仮想化データ」で確認
仮想化したテーブル名、スキーマ名を確認します。
右端の︙をクリックし、「プレビュー」も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e9a956c1-a060-1d84-4ed0-1cba6ea3d2bf.png)

　無事プレビューもできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/34efb98d-e77e-446c-cd61-f39200640ee3.png)

これで仮想化完了です。

#3. まとめ
IBM Object Storage上のCSVファイルを仮想化はフォルダ単位であることを気をつければ簡単にできます。

また[Cloud Pak for DataでGoogle Big Query上のテーブルを仮想化してアクセス](https://qiita.com/nishikyon/items/ef2d60b4687b8a6c3e39)ではGoogle Big Query上のテーブルを仮想化する方法も説明しています(Cloud Pak for DataのData Virtualizationで説明していますが、Watson Queryでも同じ方法です)。ぜひこちらも試してみてください。

以上です。