Google Colab で操作した Apache Iceberg のデータから Apache Iceberg 用の BigLake 外部テーブルを作成する方法

## 概要
本記事では、Google Colab で操作した Apache Iceberg のデータを用い、Apache Iceberg 用の BigLake 外部テーブルを作成する手順を解説します。Iceberg JSON メタデータファイルを使用してテーブルを作成し、bq コマンドを使ったメタデータの更新方法も紹介しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d2bc0731-453c-4dcc-a6d6-860ffb43ca90.png)

出所：[Apache Iceberg 用の BigLake 外部テーブルを作成する  | BigQuery  | Google Cloud](https://cloud.google.com/bigquery/docs/iceberg-external-tables?hl=ja)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/fdfaf469-9fd5-4c69-a8f2-9cf1b3297046.png)

出所：[Apache Iceberg 用の BigLake 外部テーブルを作成する  | BigQuery  | Google Cloud](https://cloud.google.com/bigquery/docs/iceberg-external-tables?hl=ja)

テーブルのメタデータ更新手順の詳細は、以下のドキュメントをご確認ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/19587b0a-f84d-4222-84cc-f9ca4a143336.png)

出所：[Apache Iceberg 用の BigLake 外部テーブルを作成する  | BigQuery  | Google Cloud](https://cloud.google.com/bigquery/docs/iceberg-external-tables?hl=ja#update-table-metadata)


Apache Iceberg 用の BigQuery テーブルの基本操作については下記の記事で紹介しています。

- [BigQuery 上で Apache Iceberg 用の BigQuery テーブル操作と Google Colab (spark)でのデータ参照の実施方法 #GoogleColaboratory - Qiita](https://qiita.com/manabian/items/a571d431df3ce8dd7521)

## 手順

### Apache Iceberg 用 BigLake 外部テーブルの作成

#### 1. GCS 上に Apache Iceberg テーブルを作成
まず、以下の記事に従って、Google Cloud Storage 上に Apache Iceberg テーブルを作成してください。

- [Google Colab による Google Cloud Storage上でのApache Icebergデータ操作方法 #Spark - Qiita](https://qiita.com/manabian/items/cb1b5eeb39595898bc78)

作成後、v2.metadata.json のパス（例：`gs://manabianqiita/iceberg/default/first_table/metadata/v2.metadata.json`）をコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/10914322-6b42-4190-9dbf-15ca247c10a4.png)

#### 2. BigLake 外部テーブルの作成
コピーした v2.metadata.json のパスを利用して、以下の SQL コマンドを実行し、外部テーブルを作成します。

```sql
CREATE EXTERNAL TABLE test.default__first_table
OPTIONS(
  format = 'ICEBERG',
  uris = ['gs://manabianqiita/iceberg/default/first_table/metadata/v2.metadata.json']
);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/70a4988c-5848-401a-bd94-53175b8ca5ac.png)

:::note warn

CONNECTION （接続）を利用せずにテーブルを作成しておりますが、Delta Lake 用の BigLake 外部テーブルドキュメントにて下記のように記述されており、おそらく本番環境では Apache Iceberg 用の BigLake 外部テーブルでも同様に非推奨です。

> 接続なしでも Delta Lake 外部テーブルを作成できますが、次の理由からおすすめしません。

出所：[Delta Lake 用の BigLake 外部テーブルを作成する  | BigQuery  | Google Cloud](https://cloud.google.com/bigquery/docs/create-delta-lake-table?hl=ja#create-tables)
:::


テーブル作成後、下記のクエリでデータ取得を確認します。

```sql
SELECT
  *
  FROM
    test.default__first_table
  ORDER BY
    id
  LIMIT 10;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/53a0ecb4-4d0b-4022-a158-f75f8ccca3a9.png)

### Apache Iceberg 用 BigLake 外部テーブルのメタデータ更新

#### 1. Google Colab にて DELETE 操作の実行
Google Colab 上で以下の Python コードを実行し、対象テーブルのレコード（id > 3）を削除します。

```python
spark.sql("""
DELETE FROM 
    default.first_table
    WHERE
        id > 3;
""")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/3e5bdf7b-4c39-4235-ba0a-078627554435.png)

#### 2. BigQuery で更新前の状態を確認
次に、BigQuery 上で再度クエリを実行し、削除操作前のデータ状態であることを確認します。

```sql
SELECT
  *
  FROM
    test.default__first_table
  ORDER BY
    id
  LIMIT 10;
```

#### 3. 最新 metadata file のパスを GCS 上で取得
GCS 上で最新の metadata file（v3.metadata.json）のパスを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/011c9296-aa15-4d9f-902b-3e1aad80f2c9.png)

#### 4. bq コマンドでメタデータ更新定義ファイルを作成
Google Cloud コンソールの bq コマンドラインを使用し、`{project_id}` を実際のプロジェクト ID に置き換えて以下のコマンドを実行します。

```bash
bq mkdef --source_format=ICEBERG \
"gs://manabianqiita/iceberg/default/first_table/metadata/v3.metadata.json" > biglake_version
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5d58b58b-7ded-41f2-a069-f325fbd42a9b.png)

この操作により、`biglake_version` という名前の JSON ファイルが作成されます。ファイル内容は以下の通りです。

```bash
cat biglake_version
```

```json
{
  "autodetect": true,
  "sourceFormat": "ICEBERG",
  "sourceUris": [
    "gs://manabianqiita/iceberg/default/first_table/metadata/v3.metadata.json"
  ]
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b03fe452-5976-4533-9f7e-14145be6a9a6.png)

#### 5. bq コマンドで BigQuery のテーブルメタデータを更新
作成した JSON 定義ファイルを基に、以下のコマンドでテーブルのメタデータを更新します。

```bash
bq update --autodetect_schema --external_table_definition=biglake_version \
{project_id}:test.default__first_table
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/189fb741-cdfd-4a2e-9c9a-c0b5bf087a43.png)

#### 6. BigQuery で更新後の状態を確認
最後に、以下のクエリを実行して、テーブル内のデータが更新されていることを確認します。

```sql
SELECT
  *
  FROM
    test.default__first_table
  ORDER BY
    id
  LIMIT 10;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/76043bae-5297-45ee-97af-ac3e2bc38e28.png)

また、テーブルのプロパティを確認すると、`Source URI(s)` が `gs://manabianqiita/iceberg/default/first_table/metadata/v3.metadata.json` となっていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/64ff4143-4031-45bb-b8ad-3373a33a9fa0.png)