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

## 概要

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

- BigQuery Data Editor
- BigQuery Job User
- 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_02`;

-- テーブルを作成
CREATE OR REPLACE TABLE `auth_test_02.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)
]);

-- ビューを作成
CREATE OR REPLACE VIEW `auth_test_02.view_01` AS
SELECT * FROM `auth_test_02.table_01`;


SELECT * FROM `auth_test_02.view_01`;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/605f896a-0fa6-4702-a390-d91d8c741234.png)

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d1da7adc-043e-4632-bc0b-4a430d1f3050.png)

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/067876f1-e0df-4ab8-9028-a4a0789b02b7.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-368703"

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

df = (
    spark.read
    .format("bigquery")
    .option("parentProject", parent_project_id)
    .option("credentials", encoded_string)
    .option("viewsEnabled", True)
    .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/af22ae28-6dc9-4e07-987d-bb238dbea9a9.png)

> Py4JJavaError: An error occurred while calling t.addCustomDisplayData.
: bigquery.storageapi.shaded.com.google.cloud.bigquery.connector.common.BigQueryConnectorException: Error creating destination table using the following query: [SELECT `id`,`name`,`score` FROM `axial-triode-368703.auth_test_02.view_01`  ]

> Caused by: bigquery.storageapi.shaded.com.google.cloud.spark.bigquery.repackaged.com.google.common.util.concurrent.UncheckedExecutionException: bigquery.storageapi.shaded.com.google.cloud.spark.bigquery.repackaged.com.google.cloud.bigquery.BigQueryException: Access Denied: Project axial-triode-368703: User does not have bigquery.jobs.create permission in project axial-triode-368703.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d3201a88-2fbc-4acf-a736-2b10357c478c.png)


### `BigQuery Job User`権限の追加

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/8bb9977a-ece3-4b92-a074-595977d929b4.png)

> Py4JJavaError: An error occurred while calling t.addCustomDisplayData.
: bigquery.storageapi.shaded.com.google.cloud.bigquery.connector.common.BigQueryConnectorException: Error creating destination table using the following query: [SELECT `id`,`name`,`score` FROM `axial-triode-368703.auth_test_02.view_01`  ]

> Caused by: bigquery.storageapi.shaded.com.google.cloud.spark.bigquery.repackaged.com.google.common.util.concurrent.UncheckedExecutionException: bigquery.storageapi.shaded.com.google.cloud.spark.bigquery.repackaged.com.google.cloud.bigquery.BigQueryException: Access Denied: Dataset axial-triode-368703:auth_test_02: Permission bigquery.tables.create denied on dataset axial-triode-368703:auth_test_02 (or it may not exist).

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a7231d8d-fe0b-4dbd-bbb2-5314627c52c6.png)


### `BigQuery Data Viewer`権限を`BigQuery Data Editor`権限に変更

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d432d3fb-e801-4313-be55-e0044443047a.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-368703'

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/3bb0f14e-757f-4eb1-bf55-45db29f5aa9f.png)

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

データを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e9b74ea5-af07-4281-8171-76861065f82f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ff4b7d5f-39c7-4089-9c49-0cc20b907904.png)


## Databricks Lakehouse Fedearation の検証

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

データを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/08a971a6-38ef-4d52-a42b-0d72ebd8aaa8.png)

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

データを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ad793b28-0ef8-4dbf-8348-41cd18a1a8cd.png)