BigQuery API操作(データ参照・テーブルコピー・GCSへのエクスポート)をGoクライアントライブラリ経由で試してみた
当エントリは、『クラスメソッド BigQuery Advent Calendar 2020』5日目のエントリです。 本アドベントカレンダーでは、12月01日〜12月25日までの25日間、弊社DA(データアナリィクス)事業本部のメンバーがBigQueryに関連するブログを公開していきます。
今回は、BigQueryのクライアントライブラリ(Go言語)経由でAPI操作を試してみたので、まとめていきます。
試したこと
ローカルからBigQueryに対して、下記のAPI操作をGoクライアントライブラリ経由で試してみました。
- テーブルデータの参照
- テーブルコピー
- GCS(Google Cloud Storage)へのエクスポート
事前準備
今回はGoのインストール方法などについては割愛させていただきます。 下記のリンクなどを参考にして簡単にインストールすることができます。 ※今回使用したgoのバージョンは、1.15.5です。
クライアントライブラリのインストール
Goがインストール済みであれば、ターミナル等から下記を実行してBigQueryのクライアントライブラリを取得できます。
go get -u cloud.google.com/go/bigquery
認証用JSONファイルの作成
クライアントライブラリを実行するために、サービスアカウントを作成しました。今回は 公式ドキュメントの手順を参考に、下記のようなJSONファイルをダウンロードしました。
※今回はJSONファイルを環境変数に設定するのではなく、コード上でJSONファイルパスを直接指定し、クライアント生成時に認証するようにしています。
{ "type": "service_account", "project_id": "ohama-nagamasa", "private_key_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "private_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "client_email": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "client_id": "XXXXXXXXXXXXXXXXXXXX", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
サンプルデータ
下記のツールを使用して、サンプルデータを作成しました。
作成したサンプルデータです。全てランダムな値です。
name,age,email ミノワ コウヘイ,62,[email protected] エチ ヒロユキ,21,[email protected] モガミ ハルヨ,19,[email protected] イナムラ ヒロ,30,[email protected] コヤナギ ミワ,38,[email protected] ムラヤマ ヒロカズ,14,[email protected] ナルセ チアキ,53,[email protected] シバサキ トキオ,27,[email protected] クスダ ヒロトシ,36,[email protected] サイトウ カホ,47,[email protected]
事前に上記のデータをBigQuery上で読み込んでおきました。
BigQueryのデータ読み込む方法については、下記ブログ等をご参照ください。
試してみた
データ参照
まずはデータ参照です。 下記のコードを使用して、テーブルデータを参照しました。 select文でデータを取得し出力している簡単なコードです。
package main import ( bq "cloud.google.com/go/bigquery" "google.golang.org/api/iterator" "google.golang.org/api/option" "context" "fmt" ) func main() { ctx := context.Background() projectID := "ohama-nagamasa" // 認証用JSONファイルのパスを指定 key := "/XXXXX/XXXXX/ohama-nagamasa-XXXXX.json" // 認証用JSONファイルを設定し、BigQuery用のclientを生成 client, err := bq.NewClient(ctx, projectID, option.WithServiceAccountFile(key)) if err != nil { fmt.Println("Failed to create client:%v", err) } defer client.Close() query(ctx, client) } func query(ctx context.Context, client *bq.Client) { q := "select name, age, email from `ohama-nagamasa.sample_demo.user` order by age" // SQLクエリを実行 it, err := client.Query(q).Read(ctx) if err != nil { fmt.Println("Failed to Read Query:%v", err) } for { var values []bq.Value err := it.Next(&values) if err == iterator.Done { break } if err != nil { fmt.Println("Failed to Iterate Query:%v", err) } fmt.Println(values) } }
実行結果です、データを参照できました〜。
$ go run query.go [ムラヤマ ヒロカズ 14 [email protected]] [モガミ ハルヨ 19 [email protected]] [エチ ヒロユキ 21 [email protected]] [シバサキ トキオ 27 [email protected]] [イナムラ ヒロ 30 [email protected]] [クスダ ヒロトシ 36 [email protected]] [コヤナギ ミワ 38 [email protected]] [サイトウ カホ 47 [email protected]] [ナルセ チアキ 53 [email protected]] [ミノワ コウヘイ 62 [email protected]]
テーブルコピー
次に下記のコードでテーブルのコピーを試してみました。 今回は「user」テーブルをコピーして「user_bkup」テーブルを作成しました。
package main import ( bq "cloud.google.com/go/bigquery" "google.golang.org/api/option" "context" "fmt" ) func main() { ctx := context.Background() projectID := "ohama-nagamasa" // 認証用JSONファイルのパスを指定 key := "/XXXXX/XXXXX/ohama-nagamasa-XXXXX.json" // 認証用JSONファイルを設定し、BigQuery用のclientを生成 client, err := bq.NewClient(ctx, projectID, option.WithServiceAccountFile(key)) if err != nil { fmt.Println("Failed to create client:%v", err) } defer client.Close() copyTable(ctx, client) } func copyTable(ctx context.Context, client *bq.Client) { dataset := client.Dataset("sample_demo") // データセットIDを指定 // コピー元の「user」テーブルから、「user_bkup」テーブルを生成するよう設定 copier := dataset.Table("user_bkup").CopierFrom(dataset.Table("user")) copier.WriteDisposition = bq.WriteTruncate job, err := copier.Run(ctx) if err != nil { fmt.Println("Failed to copy job:%v", err) } // ジョブが終了するまで待つ status, err := job.Wait(ctx) if err != nil { fmt.Println("Failed to copy job:%v", err) } if err := status.Err(); err != nil { fmt.Println("Failed to copy job:%v", err) } fmt.Println("copy fin.") }
Google Cloud Console上でコピーしたテーブルの確認ができました。
GCS(Google Cloud Storage)へのエクスポート
最後にGCSへのエクスポートを試してみます。
事前に適切な権限でGCS上にextract-demo
というバケットを作成しました。
今回はextract-demo
バケット直下に、「user」テーブルのデータをエクスポートしました。
package main; import ( bq "cloud.google.com/go/bigquery" "google.golang.org/api/option" "context" "fmt" ) func main() { ctx := context.Background() projectID := "ohama-nagamasa" // 認証用JSONファイルのパスを指定 key := "/XXXXX/XXXXX/ohama-nagamasa-XXXXX.json" // 認証用JSONファイルを設定し、BigQuery用のclientを生成 client, err := bq.NewClient(ctx, projectID, option.WithServiceAccountFile(key)) if err != nil { fmt.Println("Failed to create client:%v", err) } defer client.Close() exportTable(ctx, client) } func exportTable(ctx context.Context, client *bq.Client) { projectID := "ohama-nagamasa" datasetID := "sample_demo" table := "user" gcsRef := bq.NewGCSReference("gs://extract-demo/user.csv") // 指定したGCSのURIへデータをエクスポートするよう設定 extractor := client.DatasetInProject(projectID, datasetID).Table(table).ExtractorTo(gcsRef) extractor.DisableHeader = true job, err := extractor.Run(ctx) if err != nil { fmt.Println("Failed to extract job:%v", err) } // ジョブが終了するまで待つ status, err := job.Wait(ctx) if err != nil { fmt.Println("Failed to extract job:%v", err) } if err := status.Err(); err != nil { fmt.Println("Failed to extract job:%v", err) } fmt.Println("extract fin.") }
こちらもGoogle Cloud Consoleでエクスポートされていることを確認できました〜。
(オプションなどはあまり試せてないですが) 3つの操作をとくにハマることなく簡単に試せました!
おわりに
今回はGoクライアントライブラリを使用して、よく使いそうな3つの操作を試してみました。 ライブラリが非常に便利だったので、思ってたより簡単にAPI操作ができて良かったです。BigQueryで開発する際のイメージも湧きました! 他の言語のクライアントライブラリ、他のAPI操作やオプションなども引き続き確認していこうと思います。
『クラスメソッド BigQuery Advent Calendar 2020』 6日目は、みかみさんです。お楽しみに! 以上、DA(データアナリティクス)事業本部のナガマサでした〜!