この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
当エントリは、『クラスメソッド 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,dMqTEtY@sample.jp
エチ ヒロユキ,21,OnwHgB@example.net
モガミ ハルヨ,19,afZmJPFeXL@test.jp
イナムラ ヒロ,30,CmenAM@test.jp
コヤナギ ミワ,38,W94f1P@example.jp
ムラヤマ ヒロカズ,14,YXZ3ISWB7s@example.net
ナルセ チアキ,53,YOf99aY@sample.org
シバサキ トキオ,27,uPZjnO@sample.co.jp
クスダ ヒロトシ,36,laTjg@test.co.jp
サイトウ カホ,47,cXUwYHABnJ@sample.co.jp
事前に上記のデータを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 YXZ3ISWB7s@example.net]
[モガミ ハルヨ 19 afZmJPFeXL@test.jp]
[エチ ヒロユキ 21 OnwHgB@example.net]
[シバサキ トキオ 27 uPZjnO@sample.co.jp]
[イナムラ ヒロ 30 CmenAM@test.jp]
[クスダ ヒロトシ 36 laTjg@test.co.jp]
[コヤナギ ミワ 38 W94f1P@example.jp]
[サイトウ カホ 47 cXUwYHABnJ@sample.co.jp]
[ナルセ チアキ 53 YOf99aY@sample.org]
[ミノワ コウヘイ 62 dMqTEtY@sample.jp]
テーブルコピー
次に下記のコードでテーブルのコピーを試してみました。 今回は「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(データアナリティクス)事業本部のナガマサでした〜!