[BigQuery API(V2)] JavaでBigQueryを使う

BigQuery API(V2)をJavaで使ってみました。
今回の記事はAPIの利用を開始するのに必要なことを記事にしました。

***BigQuery APIとは***
BigQueryとは、Googleが提供するデータウェアハウスです。
大容量のデータを高速で安価に解析できることが特徴です。

BigQueryを操作するAPIはいくつも用意されています。
今回はその中のメインとなる「BigQuery API」を利用します。
|API|内容|
|---|---|
|BigQuery API|データセット、テーブル、ジョブ、ルーティンなどのコアリソースを作成、変更、削除するためのリソースを提供するメインのAPI|
|BigQuery Data Policy API|列レベルのセキュリティとデータ マスキングに関する BigQuery データポリシーを管理|
|BigQuery Connection API|BigQuery で Cloud SQL などのリモート データソースを操作できるように、リモート接続を確立するためのコントロール プレーンを提供するAPI|
|BigQuery Migration API|ユーザーが既存のデータ ウェアハウスを BigQueryに移行できるようにするメカニズムを提供するAPI|
|BigQuery Storage API|独自のアプリケーションやツールから大量のマネージド データをスキャンする必要があるユーザー向けに、高スループットのデータ読み取りを提供するAPI|
|BigQuery Reservation API|企業ユーザーがスロットや BigQuery BI Engine のメモリ割り当てなどの専用リソースをプロビジョニングし管理するためのメカニズムを提供するAPI|
|Analytics Hub|組織内および組織間でのデータ共有が容易にするためのAPI|
|BigQuery Data Transfer Service API|マネージド取り込みワークフローで利用するAPI|

BigQueryの利用料金は公式の[⧉BigQuery の料金](https://cloud.google.com/bigquery/pricing?hl=ja)を参照ください。

|No|||目次|
|---|---|---|---|
|1|||[BigQuery APIを使用するための準備](#1-bigquery-apiを使用するための準備)|
||1||[プロジェクトの作成](#11-プロジェクトの作成)|
||2||[BigQuery APIの設定](#12-bigquery-apiの設定)|
||3||[APIを使用するためのキー取得](#13-apiを使用するためのキー取得)|
|||1|[サービス アカウント](#131-サービス-アカウント)|
|||2|[OAuth2.0 クライアントID](#132-oauth20-クライアントid)|
|2|||[権限付与](#2-権限付与)|
||1||[プロジェクト単位で権限付与](#21-プロジェクト単位で権限付与)|
||2||[データセット単位で権限付与](#22-データセット単位で権限付与)|
||3||[テーブル単位で権限付与](#23-テーブル単位で権限付与)|
||4||[レコード(行レベル)単位で権限付与](#24-レコード行レベル単位で権限付与)|
|3|||[BigQuery APIを使ってみる](#3-bigquery-apiを使ってみる)|
||1||[googleライブラリの読み込み](#31-googleライブラリの読み込み)|
||2||[Bigqueryインスタンスを取得](#32-bigqueryインスタンスを取得)|
|||1|[サービスアカウントを利用する場合](#321-サービスアカウントを利用する場合)|
|||2|[OAuth 2.0 クライアントIDを利用する場合](#322-oauth-20-クライアントidを利用する場合)|
||3||[プログラムの実行](#33-プログラムの実行)|
|4|||[いろいろとAPIを叩いてみる](#4-いろいろとapiを叩いてみる)|
||1||[v2.datasets](#41-v2datasets)|
||2||[v2.jobs](#42-v2jobs)|
||3||[v2.models](#43-v2models)|
||4||[v2.projects](#44-v2projects)|
||5||[v2.routines](#45-v2routines)|
||6||[v2.rowAccessPolicies](#46-v2rowAccessPolicies)|
||7||[v2.tabledata](#47-v2tabledata)|
||8||[v2.tables](#48-v2tables)|

# 1. BigQuery APIを使用するための準備
設定は下記から行います。
[⧉Google クラウド プラットフォーム](https://console.cloud.google.com/)

やることは下記の４つです。
[1. GCPプロジェクトの作成](#11-プロジェクトの作成)
[2. BigQuery APIの有効化](#12-bigquery-apiの設定)
[3. プログラムで使用するキーの取得](#13-apiを使用するためのキー取得)

3.は、サービスアカウントかOAuth2.0を利用する2つの方法があります。
BigQuery APIはAPIキーの利用はサポートしていません。

### 1.1. プロジェクトの作成
まずはGCPでプロジェクトを作成します。
詳細はこちらの記事を参照ください
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.1. プロジェクトの作成)](https://qiita.com/doran/items/3d43f776188b2281044c/#11-プロジェクトの作成)

### 1.2. BigQuery APIの設定
BigQuery APIを使えるようにします。

|No|手順||
|---|---|:-:|
|1|メニューの 「APIとサービス」 -> 「ライブラリ」 を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2fda7515-ffdf-11d7-4142-fed896cc8413.png">|
|2|Bigquery api と入力して「BigQuery API」を検索します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f4d2d13c-0ef8-f4e7-f3b4-1bc8aadbc595.png">|
|3|「有効にする」ボタンを押して「BigQuery API」を使用可能にします。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/e724ec7c-5bcb-5e79-7eab-349915e69ce7.png">|

### 1.3. APIを使用するためのキー取得
プログラムからAPIを実行するための準備を行います。

#### 1.3.1. サービス アカウント
同じ内容を下記の記事に掲載してますので、下記の記事を参照ください。
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.3. Googleサービスアカウントの作成)](https://qiita.com/doran/items/3d43f776188b2281044c/#13-googleサービスアカウントの作成)

#### 1.3.2. OAuth2.0 クライアントID
同じ内容を下記の記事に掲載してますので、下記の記事を参照ください。
[⧉[Google Drive API v3] JavaでDrive APIを使う(1.3.2. OAuth2.0 クライアントID)](https://qiita.com/doran/items/15b2c59adb410ddeeb8a/#132-oauth20-クライアントid)

# 2. 権限付与
APIを使用してアクセスするには権限の付与が必須です。
プロジェクト単位、データセット単位、テーブル単位、
さらにはレコード(行レベル)単位で権限を付与できます。

APIをいろいろと叩く予定なので、ロールに「BigQuery管理者」を指定していますが、
状況に応じて適切に設定してください。

### 2.1. プロジェクト単位で権限付与
プロジェクト単位で権限を付与します。
|No|手順||
|---|---|:-:|
|1|メニュー「IAMと管理」 -> 「IAM」を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/b3c4aa56-621f-02df-fe8f-1f8b3a331b4b.png">|
|2|「アクセス権を付与」を選択します。|<img width=280 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2ca49fce-d4ef-6014-2444-feb5a8ea0454.png">|
|3|下記を入力・設定して「保存」ボタンを押します。<br><br>新しいプリンシパル：サービスアカウントメールアドレスか、OAuth2.0認証を行うメールアドレス<br>ロールを選択：BigQuery管理者|<img width=280 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/df893db5-e7b3-3532-babf-66143aa4068c.png">|

### 2.2. データセット単位で権限付与
データセットの単位で権限を付与します。

|No|手順||
|---|---|:-:|
|1|対象のデータセットを選択し、上部メニューの「共有」->「権限」を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f5b3cce2-d761-5c4b-919e-ede8238cefa8.png">|
|2|権限の共有画面が表示されるので「プリンシパルを追加」を押します。|<img width=280 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/b00c49cb-5f24-eabe-a66c-9dc07952baf0.png">|
|3|下記を入力・設定して「保存」ボタンを押します。<br><br>新しいプリンシパル：サービスアカウントメールアドレスか、OAuth2.0認証を行うメールアドレス<br>ロールを選択：BigQuery管理者|<img width=280 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/21f8fbc7-ea2b-9026-00f0-c671b647d44b.png">|

### 2.3. テーブル単位で権限付与
データセットの単位で権限を付与します。

|No|手順||
|---|---|:-:|
|1|対象のテーブルを選択し、上部メニューの「共有」を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/93155682-5357-9154-6a4f-91970696db9e.png">|
|2|権限の共有画面が表示されるので「プリンシパルを追加」を押します。|<img width=280 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/c7da4795-3e0b-bbdd-40b6-921d7fc9e079.png">|
|3|下記を入力・設定して「保存」ボタンを押します。<br><br>新しいプリンシパル：サービスアカウントメールアドレスか、OAuth2.0認証を行うメールアドレス<br>ロールを選択：BigQuery管理者|<img width=280 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/4fb778a2-508a-0f0f-0cd5-b51d11fc142a.png">|

### 2.4. レコード(行レベル)単位で権限付与
レコード(行レベル)の単位で権限を付与します。

詳細は、公式の[⧉ BigQuery の行レベルのセキュリティの概要](https://cloud.google.com/bigquery/docs/row-level-security-intro?hl=ja)を参照ください。

# 3. BigQuery APIを使ってみる
### 3.1. googleライブラリの読み込み
BigQuery APIを使用するためにライブラリのパスを設定します。
私の環境はpom.xmlで下記を指定しています。
Javaのバージョンは21を使用しています。

```xml
<dependencies>
    <dependency>
        <groupId>com.google.api-client</groupId>
        <artifactId>google-api-client</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>google-cloud-bigquery</artifactId>
    </dependency>
    <!-- OAuth2.0でAPIを使う場合は下記を追加してください。 -->
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client-jetty</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>libraries-bom</artifactId>
            <version>26.34.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
```

### 3.2. BigQueryインスタンスを取得

#### 3.2.1. サービスアカウントを利用する場合
コード中の「JSONファイルのパス」は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.3. Googleサービスアカウントの作成)](https://qiita.com/doran/items/3d43f776188b2281044c#13-googleサービスアカウントの作成)
で取得したJSONファイルのパスを指定してください。

コード中の「スコープ」は、
実行するAPIによって異なるので適時に変更してください。

```java
private static Bigquery getBigquery() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    GsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    try(InputStream input = new FileInputStream("JSONファイルのパス")){
        GoogleCredentials credentials = GoogleCredentials
                .fromStream(input)
                .createScoped(Arrays.asList("スコープ"));
        
        return new Bigquery(transport, jsonFactory, new HttpCredentialsAdapter(credentials));
    }
}
```
#### 3.2.2. OAuth 2.0 クライアントIDを利用する場合
コード中の「JSONファイルのパス」は、
[⧉[Google Drive API v3] JavaでDrive APIを使う(1.3.2.1 認証情報の作成)](https://qiita.com/doran/items/15b2c59adb410ddeeb8a/#1321-認証情報の作成)
で取得したJSONファイルのパスを指定してください。

コード中の「認証情報を保存するフォルダパス」は、
認証情報が保存されるフォルダのパスを指定してください。
このコードを実行するとOAuth同意画面が表示されます。
ユーザーが同意をすると認証情報を保存するフォルダにファイルが生成されます。
このファイルが存在した場合は、再度実行してもOAuth同意画面は表示されません。

コード中の「スコープ」は、
実行するAPIによって異なるので適時に変更してください。
途中でスコープを変更した場合は再度のOAuth同意が必要になるので
「認証情報を保存するフォルダパス」にあるファイルを削除するか、パスを変えてください。
```java
private static Bigquery getBigquery() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    GsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    try(Reader reader = new InputStreamReader(new FileInputStream("JSONファイルのパス"))){
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory,reader);

        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                transport, jsonFactory, clientSecrets, 
                Arrays.asList("スコープ"))
            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File("認証情報を保存するフォルダパス")))
            .build();
        
        LocalServerReceiver receiver = new LocalServerReceiver.Builder().build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
        
        return new Bigquery.Builder(transport, GsonFactory.getDefaultInstance(), credential).build();
    }
}
```

### 3.3. プログラムの実行
プログラムを動かします。

サンプルではプロジェクト内のデータセットの一覧を取得しています。
なお、データセットにアクセス可能な権限がないと取得することはできません。
[必要に応じてデータセットに権限を付与してください。](#2-権限付与)

```java
public static void main(String[] args) throws Exception{
    Bigquery bigquery = getBigquery();
    Bigquery.Datasets datasets = bigquery.datasets();
    
    Bigquery.Datasets.List list = datasets.list("プロジェクトID");
    
    DatasetList res = list.execute();
    System.out.println(res);
}
```
# 4. いろいろとAPIを叩いてみる
いろいろなAPIを叩いてみます。

### 4.1. v2.datasets
データセットに関する操作

|メソッド|概要|記事|
|---|---|---|
|delete|データセットを削除|[⧉[BigQuery API(V2)] Javaでデータセットを生成・更新・削除する](https://qiita.com/doran/items/4514568af5737cd9c8c4)|
|get|指定したデータセットの情報を取得|[⧉[BigQuery API(V2)] Javaでデータセットを取得する](https://qiita.com/doran/items/9bde7ca1d1c608d4f416)|
|insert|データセットを作成|[⧉[BigQuery API(V2)] Javaでデータセットを生成・更新・削除する](https://qiita.com/doran/items/4514568af5737cd9c8c4)|
|list|データセットの一覧を取得|[⧉[BigQuery API(V2)] Javaでデータセットを取得する](https://qiita.com/doran/items/9bde7ca1d1c608d4f416)|
|patch|データセットの情報を更新|[⧉[BigQuery API(V2)] Javaでデータセットを生成・更新・削除する](https://qiita.com/doran/items/4514568af5737cd9c8c4)|
|undelete|データセットの削除を取り消す|[⧉[BigQuery API(V2)] Javaでゴミ箱に移動されたデータセットを復元する](https://qiita.com/doran/items/16bfac52c0116502e3a7)|
|update|データセットの情報を上書き|[⧉[BigQuery API(V2)] Javaでデータセットを生成・更新・削除する](https://qiita.com/doran/items/4514568af5737cd9c8c4)|

### 4.2. v2.jobs
ジョブに関する操作

|メソッド|概要|記事|
|---|---|---|
|cancel|ジョブの実行をキャンセル|[⧉[BigQuery API(V2)] JavaでBigQueryのジョブの実行をキャンセルする](https://qiita.com/doran/items/7bcf0db1c93b742516be)|
|delete|ジョブを削除|[⧉[BigQuery API(V2)] JavaでBigQueryのジョブを生成・削除する](https://qiita.com/doran/items/0366dae7ad1fdc698d1a)|
|get|指定したジョブの情報を取得|[⧉[BigQuery API(V2)] JavaでBigQueryのジョブを取得する](https://qiita.com/doran/items/d0e8c55bad94e643adf1)|
|getQueryResults|ジョブの実行結果を取得|[⧉[BigQuery API(V2)] JavaでBigQueryのジョブの実行結果を取得する](https://qiita.com/doran/items/1df557ec4f4dfb5d3526)|
|insert|ジョブを生成＆実行|[⧉[BigQuery API(V2)] JavaでBigQueryのジョブを生成・削除する](https://qiita.com/doran/items/0366dae7ad1fdc698d1a)|
|list|ジョブのリストを取得|[⧉[BigQuery API(V2)] JavaでBigQueryのジョブを取得する](https://qiita.com/doran/items/d0e8c55bad94e643adf1)|
|query|クエリを実行|[⧉[BigQuery API(V2)] JavaでBigQueryでクエリを実行する](https://qiita.com/doran/items/e3c6fcef31480a3c5492)|

### 4.3. v2.models
BigQuery ML モデルに関する操作

|メソッド|概要|記事|
|---|---|---|
|delete|モデルを削除|[⧉[BigQuery API(V2)] JavaでBigQuery ML モデルの情報を更新・削除する](https://qiita.com/doran/items/5cc90833700f71c9fdc0)|
|get|指定したモデルの情報を取得|[⧉[BigQuery API(V2)] JavaでBigQuery ML モデルの情報を取得する](https://qiita.com/doran/items/5abe8a4677d939a69557)|
|list|モデルのリストを取得|[⧉[BigQuery API(V2)] JavaでBigQuery ML モデルの情報を取得する](https://qiita.com/doran/items/5abe8a4677d939a69557)|
|patch|モデルの情報を更新|[⧉[BigQuery API(V2)] JavaでBigQuery ML モデルの情報を更新・削除する](https://qiita.com/doran/items/5cc90833700f71c9fdc0)|

### 4.4. v2.projects
プロジェクトに関する操作

|メソッド|概要|記事|
|---|---|---|
|getServiceAccount|指定したプロジェクトのサービスアカウントのメールアドレスを取得|[⧉[BigQuery API(V2)] Javaでサービスアカウントのメールアドレスを取得する](https://qiita.com/doran/items/e5242fa6252a00155bac)|
|list|プロジェクトの一覧を取得|[⧉[BigQuery API(V2)] Javaでアクセス可能なプロジェクト一覧を取得する](https://qiita.com/doran/items/c53c04af4ba8d06bbf51)|

### 4.5. v2.routines
ルーティンに関する操作

|メソッド|概要|記事|
|---|---|---|
|delete|ルーティンを削除|[⧉[BigQuery API(V2)] Javaでデータセットのルーティンを生成・更新・削除する](https://qiita.com/doran/items/adca8f2fb46624e2e84e)|
|get|指定したルーティンの情報を取得|[⧉[BigQuery API(V2)] Javaでデータセットのルーティン情報を取得する](https://qiita.com/doran/items/a4aa20982398d70ae394)|
|insert|ルーティンを作成|[⧉[BigQuery API(V2)] Javaでデータセットのルーティンを生成・更新・削除する](https://qiita.com/doran/items/adca8f2fb46624e2e84e)|
|list|ルーティンのリストを取得|[⧉[BigQuery API(V2)] Javaでデータセットのルーティン情報を取得する](https://qiita.com/doran/items/a4aa20982398d70ae394)|
|update|ルーティンの情報を更新|[⧉[BigQuery API(V2)] Javaでデータセットのルーティンを生成・更新・削除する](https://qiita.com/doran/items/adca8f2fb46624e2e84e)|

### 4.6. v2.rowAccessPolicies
行レベルのアクセス制御に関する操作

|メソッド|概要|記事|
|---|---|---|
|getIamPolicy|行レベルのアクセス制御ポリシーを取得|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの行レベルのアクセス制御ポリシーのリストを取得する](https://qiita.com/doran/items/d8424175c7dc1d3740fb)|
|list|行レベルのアクセス制御ポリシーのリストを取得|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの行レベルのアクセス制御ポリシーのリストを取得する](https://qiita.com/doran/items/d8424175c7dc1d3740fb)|
|testIamPermissions|行レベルのアクセス許可をテスト|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの行レベルのアクセス許可をテストする](https://qiita.com/doran/items/8cda115e79bc8ed8fb2b)|

### 4.7. v2.tabledata
レコードに関する操作

|メソッド|概要|記事|
|---|---|---|
|insertAll|BigQueryにレコードを挿入|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの行(レコード)を挿入する](https://qiita.com/doran/items/69a1d3029ef77a3acd9d)|
|list|テーブルの内容を行(レコード)単位のリストで取得|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの行(レコード)を取得する](https://qiita.com/doran/items/b854940293d7c47a16d3)|

### 4.8. v2.tables
テーブルに関する操作

|メソッド|概要|記事|
|---|---|---|
|delete|テーブルを削除|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルを生成・更新・削除する](https://qiita.com/doran/items/339d7904682d03756b50)|
|get|指定したテーブルの情報を取得|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの情報を取得する](https://qiita.com/doran/items/57468203da657921fa2d)|
|getIamPolicy|テーブルのアクセス制御ポリシーを取得|[⧉[BigQuery API(V2)] Javaでテーブルのアクセス制御ポリシーを取得する](https://qiita.com/doran/items/3758254588d3e2f8fadd)|
|insert|テーブルを作成|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルを生成・更新・削除する](https://qiita.com/doran/items/339d7904682d03756b50)|
|list|テーブル情報のリストを取得|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルの情報を取得する](https://qiita.com/doran/items/57468203da657921fa2d)|
|patch|テーブルの情報を更新|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルを生成・更新・削除する](https://qiita.com/doran/items/339d7904682d03756b50)|
|setIamPolicy|テーブルにアクセス制御ポリシーを設定|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルにアクセス制御ポリシーを設定する](https://qiita.com/doran/items/c63d9fcfc65fb2391d4d)|
|testIamPermissions|テーブルのアクセス許可をテスト|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルのアクセス許可をテストする](https://qiita.com/doran/items/90f1947665453a5b7ea2)|
|update|テーブルの情報を上書き更新|[⧉[BigQuery API(V2)] JavaでBigQueryテーブルを生成・更新・削除する](https://qiita.com/doran/items/339d7904682d03756b50)|

<br>
<br>
おしまい。。