Google Colab を Iceberg クライアントとして Databricks の UniForm が有効な Delta テーブルを読み取る方法

## 概要

Google Colab の Spark を Iceberg クライアントとして Databricks の UniForm が有効な Delta テーブルを読み取る方法を紹介します。

## 手順

### Databricks にてカタログとテーブルを構築

カタログ作成、テーブル作成、及び、データ挿入を実施します。テーブル作成時には、 Iceberg の

```sql
%sql
CREATE CATALOG delta_uniform;
```

```sql
%sql
CREATE TABLE delta_uniform.default.nation_iceberg (
  n_nationkey  integer
  ,n_name       string
  ,n_regionkey  integer 
  ,n_comment    string
)
TBLPROPERTIES(
  'delta.columnMapping.mode' = 'name',
  'delta.enableIcebergCompatV2' = 'true',
  'delta.universalFormat.enabledFormats' = 'iceberg'
);
```

```sql
%sql
INSERT OVERWRITE delta_uniform.default.nation_iceberg
SELECT
  n_nationkey
  ,n_name
  ,n_regionkey 
  ,n_comment
FROM
  samples.tpch.nation
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/fe031028-aa88-4a3c-ab47-86fb74917db8.png)

25 レコードあることを確認します。

```sql
%sql
SELECT * FROM delta_uniform.default.nation_iceberg;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/016332a0-9c98-4afc-813f-8c50d8e6737a.png)

### Databricks にて Token を取得

表示された値を控えます。

```python
%pip install databricks-sdk --upgrade --q
dbutils.library.restartPython()
```

```python
from databricks.sdk import WorkspaceClient

client = WorkspaceClient()
token_response = client.tokens.create(
    lifetime_seconds=3600,
    comment="PAT token for API access",
)
pat_token = token_response.token_value

print(pat_token)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e18e4e09-ae14-4a86-9e0a-0e90b105a90c.png)

### Google Colab の Spark から  Iceberg クライアントとしてアクセス

Google Colab のノートブックを作成し、 Spark のバージョンを確認します。

```python
!pyspark --version
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f048a237-ceb8-4b3a-a022-17fe89b73c0f.png)

Databricks に関する情報をセットします。token には前の手順で取得した token を設定します。

```python
# Databricks に関する情報をセット
catalog_name = "delta_uniform"
workspace_url = "adb-XXXX.XX.azuredatabricks.net"
token = "dkeaxxxx-3"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/8105b49a-d2e3-4250-9c47-06187583f6b5.png)

SparkSession を定義します。本手順は Azure Storage を想定しています。

```python
from pyspark.sql import SparkSession


spark = (
    SparkSession.builder.appName("iceberg_lab")
    .config(
        "spark.jars.packages",
        "org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.8.1,"
        "org.apache.iceberg:iceberg-azure-bundle:1.8.1",
    )
    .config("spark.sql.extensions","org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions",)
    .config(f"spark.sql.catalog.spark_catalog", "org.apache.iceberg.spark.SparkCatalog")
    .config(f"spark.sql.catalog.spark_catalog.type", "rest")
    .config(f"spark.sql.catalog.spark_catalog.uri",f"https://{workspace_url}/api/2.1/unity-catalog/iceberg")
    .config(f"spark.sql.catalog.spark_catalog.token", token)
    .config(f"spark.sql.catalog.spark_catalog.warehouse", catalog_name)
    .getOrCreate()
)
spark
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b0d5354f-0074-4778-b07e-ea294929e8dc.png)

:::note info

利用するクラウドベンダーごとに異なる Apache Iceberg の iceberg バンドルを指定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a04d324d-9875-475c-aa13-9dd4d88fdde2.png)

出所：[Iceberg クライアントから Databricks テーブルを読み取る | Databricks Documentation](https://docs.databricks.com/aws/ja/external-access/iceberg)

:::

データを表示できることを確認します。

```python
df = spark.table("default.nation_iceberg")
df.show(truncate=False)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b35b45ab-7c22-41dc-9dfb-e2b915e959f1.png)