Databricks にて Spark-BQ コネクターによりテーブルを参照する際に必要な権限に関する検証

## 概要

Databricks にて BigQuery から Spark-BQ コネクター（Apache Spark SQL connector for Google BigQuery）によりテーブルを参照する際に必要となる Google Cloud の権限に関する検証結果を共有します。検証の結果、下記の権限が必要となります。

- BigQuery Data Viewer
- BigQuery Read Session User

Databricks Federation を実施際の動作も確認します。Databricks Runtime 16.1 以降のクラスターでは Spark Connector が利用される仕様変更がされたため、 16.4 と 15.4 のバージョンでそれぞれ実行しています。仕様変更内容について下記の記事で整理しています。

- [Databricks の Lakehouse federation にて BigQuery をソースにしている場合に Databricks Runtime 16.1 以降のクラスターでは Spark Connector が利用される仕様に変更 #Databricks - Qiita](https://qiita.com/manabian/items/4e87c7d185840847c674)

本記事は下記シリーズの一部です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/1bb4805e-9f67-49e9-8e72-36036bf4310c.png)

出所：[Databricks で BigQuery のデータを取得する方法の徹底ガイド - Qiita](https://qiita.com/manabian/items/7097a9c31de23752d58a)

## 事前準備

### BigQuery にオブジェクトを作成

```sql
-- データセットを作成
CREATE SCHEMA IF NOT EXISTS `auth_test_01`;

-- テーブルを作成
CREATE OR REPLACE TABLE `auth_test_01.table_01` AS
SELECT *
FROM UNNEST([
  STRUCT(1 AS id, 'Alice' AS name, 100 AS score),
  STRUCT(2 AS id, 'Bob'   AS name,  95 AS score),
  STRUCT(3 AS id, 'Carol' AS name,  98 AS score)
]);


SELECT * FROM `auth_test_01.table_01`;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2904599c-e1cb-4f37-8f2c-cc7b51eca5f4.png)

### サービスアカウント作成後にキーを取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2e696e06-6b7f-4055-9221-9d60ac03cb44.png)

### BigQuery を Databricks の外部カタログに登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/07683852-2ae0-4354-8572-90f49c14a4ec.png)

### Databricks にてノートブック作成後に実行するコードを記述

```python
json_str = b"""{json_key}"""
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/3bee7020-0d98-4d0b-8f3d-22afac74fade.png)


```python
import base64

encoded_string = base64.b64encode(json_str).decode('utf-8')

# プロジェクト ID を設定
parent_project_id = "axial-triode-XXXXX"

# データ取得元のテーブル名を設定
table_name = "auth_test_01.table_01"

df = (
    spark.read
    .format("bigquery")
    .option("parentProject", parent_project_id)
    .option("credentials", encoded_string)
    .option("table",table_name)
    .load()
)

df.limit(50).display()
```

## 権限検証

### `BigQuery Data Viewer`権限の追加

権限不足によるエラーが発生します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/12c56238-3a66-4772-bd28-ab0aea7ec35d.png)

> Py4JJavaError: An error occurred while calling t.addCustomDisplayData.
: bigquery.storageapi.shaded.com.google.cloud.spark.bigquery.repackaged.com.google.api.gax.rpc.PermissionDeniedException: bigquery.storageapi.shaded.com.google.cloud.spark.bigquery.repackaged.io.grpc.StatusRuntimeException: PERMISSION_DENIED: request failed: the user does not have 'bigquery.readsessions.create' permission for 'projects/axial-triode-XXXXX'

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/16803032-861d-4552-907c-1803731d98a7.png)

### `BigQuery Read Session User`権限の追加

データを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a0ccfe82-2cc3-4be3-823f-33ca352ff81b.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f412b796-6ce8-4a8f-a6cd-f9b87ab24a1a.png)


## Databricks Lakehouse Fedearation の検証

### Databricks Runtime 16.4 での実行可否確認

データを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5771d4a1-1732-4f0c-9c02-fc1a6a355312.png)

### Databricks Runtime 15.4 での実行可否確認

権限不足によるエラーが発生します。

> [FAILED_JDBC.UNCLASSIFIED] Failed JDBC jdbc: on the operation: Failed table existence check: auth_test_01.table_01 SQLSTATE: HV000

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d2c68b32-9332-4b8d-9972-fe5131e46fc1.png)