watsonx.data: Sparkエンジンを使用したデータ取り込みジョブの作成

watsonx.data(IBM Cloud SaaS版)のWeb UIでIBM Analytics Engine(Spark)エンジンを使用したデータ取り込みジョブの作成ができるようになりました(作成後はもちろん実行されます)。

尚、この投稿の作成時（2023年12月20日）は別サービスのIBM Analytics Engine(Spark)エンジンが必須でしたが、watsonx.data(IBM Cloud SaaS版)内部にSparkエンジンができましたので、別サービスは必須ではになくなりました(2024/6/11記載)。

当記事はその方法を説明します。またCSVファイルでもできるのですが、この記事はParquetファイルの取り込みをやっています。
自分のファイルでも可能ですが、ここではサンプルとして TLC Trip Record Data(NYのタクシーのオープンデータ)をテーブルに取り込んでみます。**環境はIBM Cloudです。**

# 0. 前提
- IBM watsonx.dataのインスタンスがあること 
- IBM Analytics Engineのインスタンス があること
  - ない場合は「[1. IBM Analytics Engine Spark インスタンスの作成](https://qiita.com/nishikyon/items/fdaf99066cece2b10ac8)」を参考に作成してください。
<p>

- アクセスするuseridにwatsonx.dataに対してIAMで` MetastoreAccess role`があること(2024/6/11 New)


**Sparkにwatsonx.dataのSpark(native spark)を使用する場合**
- Sparkエンジンが追加されていること
  - ない場合は追加する
    - 　参考：[watsonx.data: Sparkエンジンの追加](https://qiita.com/nishikyon/items/0cb71bbc8d89b647ea54)


**SparkにIBM Analytics Engineを使用する場合**
- IBM Analytics Engineのインスタンス があること
  - ない場合は「[1. IBM Analytics Engine Spark インスタンスの作成](https://qiita.com/nishikyon/items/fdaf99066cece2b10ac8)」を参考に作成してください。
<p>

- エンジンに「IBM Analytics Engine(Spark)」　のエンジンが追加されてること
    - 追加されてない場合は[watsonx.data: IBM Analytics Engine(Spark)エンジンを使用したデータ取り込みジョブの作成](https://qiita.com/nishikyon/items/6fd5bdf690632a136b55)の「[2. 前準備2: エンジンに「IBM Analytics Engine(Spark)」　のエンジンを追加](https://qiita.com/nishikyon/items/6fd5bdf690632a136b55#2-%E5%89%8D%E6%BA%96%E5%82%992-%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3%E3%81%ABibm-analytics-enginespark%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%92%E8%BF%BD%E5%8A%A0)」を参考に追加してください
<br>
<br>

- watsonx.dataのカタログがカタログ・タイプ「Apache Iceberg」で1つ以上登録済みであること
- 取り込み先のテーブルがIceberg 形式で作成済であること(*)

(*)作成されてない場合は以下の前準備で作ってみてください。

# 1. 前準備1（オプション）: サンプルデータのダウンロードとサンプルテーブルの作成
もうすでにデータを取り込みたいテーブルがある場合は、ここはスキップしてください。
サンプルのテーブルを作りたい方は以下を実施してください。

### 1-1. TLC Trip Record Data(NYのタクシーのオープンデータ)のダウンロード
[TLC Trip Record Data](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page)より、2022年のJanuaryのYellow Taxi Trip Recordsをダウンロードします。
`yellow_tripdata_2022-01.parquet`というファイルが」ダウンロードされます。
![taxi_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/bb95d2fb-4fbf-29b9-2fb6-5de296173433.jpeg)



### 1-2. サンプルテーブルの作成
Icebergのカタログ上でスキーマを作成後、以下のDDLでテーブルを作成してください。
`lakehouse`は自分のカタログ名、`taxi`は自分のスキーマ名に変更してください。
```sql
CREATE TABLE lakehouse.taxi.yellow_taxi_2022 (
   "VendorID" bigint,
   "tpep_pickup_datetime" timestamp,
   "tpep_dropoff_datetime" timestamp,
   "passenger_count" double,
   "trip_distance" double,
   "RatecodeID" double,
   "store_and_fwd_flag" varchar,
   "PULocationID" bigint,
   "DOLocationID" bigint,
   "payment_type" bigint,
   "fare_amount" double,
   "extra" double,
   "mta_tax" double,
   "tip_amount" double,
   "tolls_amount" double,
   "improvement_surcharge" double,
   "total_amount" double,
   "congestion_surcharge" double,
   "airport_fee" double
)
WITH (
   format = 'PARQUET'
)
```

# 2. 前準備2: エンジンに「IBM Analytics Engine(Spark)」　のエンジンを追加

取り込みジョブの作成で使用するためにエンジンに「IBM Analytics Engine(Spark)」　のエンジンを追加します。既に追加済みの場合、watsonx.dataのSpark(native spark)を使用する場合はスキップしてください。

### 2-1. インフラストラクチャー・マネージャーの右上「コンポーネントの追加」から「エンジンの追加」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/358051f2-e288-6e94-b238-3804e62d1774.png)

### 2-2. 「エンジンの追加」入力画面に必要事項を記入し、「レジスター」をクリック
**タイプ:**
`IBM Analytics Engine(Spark)`を選択

**表示名：**
表示させたい名前を記入

**インスタンスAPIポイント：**
<以下の手順で取得します>
1. IBM Cloudにログインし,リソースリストを表示します。
https://cloud.ibm.com/resources
(ログインしていない場合はログイン画面の後、リソースリスト画面になります)
2. 「分析」セクションにあるAnalytics Engineインスタンスの名前をクリックして詳細を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e5326ce1-a9b2-773d-3c18-342ab427aee7.png)

3. 「サービス資格情報」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e9a4db66-623d-8704-26ff-0c887c5f717a.png)

2. 新規資格情報 をクリックして、新しいサービス資格情報を作成します。
名前を入力し、役割を選択して、 追加 をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/7f2630f2-f77d-df47-c398-4036f5d5488a.png)

3.作成された資格情報をクリックし中身を表示し、`instance_api`をクリップボードにコピーし、入力フィールドに貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/1062314e-80ea-9a1f-85e9-a488bf2f6e98.png)



**APIキー：**
<以下の手順で取得します>
上記インスタンスAPIポイントで使用した 「サービス資格情報」をクリックし中身を表示し、`apikey`をクリップボードにコピーし、入力フィールドに貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ee80f81f-6aad-e1d6-0392-e6b36f5695d4.png)

入力が完了したら、「レジスター」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/ae348c0c-7033-f38d-08b6-ad44dbcc6f4f.png)


無事登録されると、以下のように「インフラストラクチャー・マネージャー」に表示されるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/8600d674-d28e-7b6f-ee17-602b3f526188.png)



# 3. 取り込み用データをCOSにアップロード
wastonx.dataに登録済のオブジェクトストレージのバケットに、取り込み用データをアップロードします。

ここではサンプルとして1-1でダウンロードしたファイルを、アップロードします。
この例ではwastonx.dataに登録済のオブジェクトストレージ`nishito-iceberg` というバケットの`data_file`というフォルダーにアップロードしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/16e7b734-7027-52bf-8dfc-3c169cd25591.png)



# 4. 　取り込みジョブの作成

### 4-1. 「データの取り込み」画面の表示
watsonx.dataの左側のメニューから「データ・マネージャー」のアイコンをクリックし、「データ・マネージャー」を表示します。次に「取り込みジョブの作成」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/78145746-1d48-26f5-07fe-75ca8ec2a791.png)


### 4-2. 「エンジン」情報の入力
**エンジン:**
使用するSparkエンジンを選択します。

**ジョブ・リソースの構成:**
サイズを選びます

最後に「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a2eff6cf-4830-3d2a-b77b-6d789ab49944.png)

### 4-3. 「Select file(s)」情報の入力
「Select remote files」 をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/87f89d91-1aba-f1b2-7872-c8a6c80e2287.png)




**Bucket**
「3. 取り込み用データをCOSにアップロード」でアップロードしたCOSを選択

**Select file type**
ここでは`Parquet'を選択

**Browse remote files**
「3. 取り込み用データをCOSにアップロード」でアップロードした　**ファイル**または**フォルダー**にチェックを入れる。

上記をセットしたら「Next」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/31bf8495-c208-62c4-e070-832addf2f84c.png)

最後に「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/68959bb0-b205-82b1-be89-9e332c84e960.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c1ba65c1-1434-fe90-90dc-91ced2236748.png)

### 4-4. 「ターゲット」情報の入力
取り込み先のテーブルの以下を入力します。サンプルを使用する場合は、「1-2. サンプルテーブルの作成」で作成したテーブルの情報になります。
- カタログ名
- スキーマ名
- テーブル名

内容を確認して「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/69d067d2-4d83-ea4c-42db-8ca26e4d5ccd.png)



### 4-5. 「サマリー」を確認して、「取り込み」をクリック
「サマリー」を確認後、「取り込み」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/558067d4-8e01-211d-82e4-0e3551ecef44.png)


ジョブが登録されます：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/14276df9-f8a2-27ae-f3da-4ebfbff9be4c.png)


# 5. 　取り込みジョブの終了確認
状況が「終了」になれば完了です。完了後、データが無事取り込まれたか確認してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/8db7f886-d5f8-ee46-3387-bb631fd89d5c.png)

もし状況が「失敗」の場合はジョブIDをクリックすると、エラーメッセージが表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/4b5d3908-3c6b-e2db-99bd-b385feff4d6d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e51c5a0f-8c53-dce6-c9c9-4370dde0c6ba.png)

データ取り込みジョブの作成については以上で完了です。

# 6. python実行ファイル
この「データ取り込みジョブの作成」をすると、実際は「ターゲット」テーブルのあるオブジェクトストレージのバケットに、 IBM Analytics Engine(Spark)で動作させたpython実行ファイルが書き込まれます。
で、そのまま残っています(!!!)
ジョブIDがついたフォルダーが作成されていて、その中にpythonのファイルが入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c215f2b8-85ee-beb5-fbc3-bbe6c933d774.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/8312b782-37fb-c3f4-f919-19cdea73e93c.png)

こちらはそのまま「[IBM Analytics Engine Sparkからwatsonx.data を操作: 「3. Sparkによる処理」](https://qiita.com/nishikyon/items/732a9c1e56de7560356c)」でそのまま図1の⑥のファイルとして使用可能です。

GUIではなく、バッチプログラムベースでやりたい時は再利用可能です。でもファイル残ったままだとゴミがたまるような気がするので、今後修正されるかもしれません。

以上です。