結構ハマって調べたので、まとめました。2017-07-22 時点の情報です。
作業しながら見つけたので、少し間違っている可能性はあります。
対象読者
- BigQueryを用意したがAPIとして呼びたい
- Go(golang)を使いたい
- Herokuなど、Webアプリケーションから動かしたい
手順
ざっと以下の手順。
- GCP上でサービスアカウントを登録
- Herokuで環境変数の設定
- Goから呼べるようにする
※Herokuの使い方やBigQueryの作成、細かい用語の説明などは別の方のドキュメントを参考にしてください。
GCP上でサービスアカウントの登録
対象のプロジェクトでGCPの「IAMと管理」を開く
サービスアカウントを追加
役割は以下。役割を間違えると、403 Access Denied
となります。
- BigQuery データ閲覧者
- BigQuery ユーザー
Json形式で鍵をダウンロード
手順に従えばダウンロードは問題なくできます。
Herokuで環境変数の設定をする
Herokuの以下画面で環境変数を設定する。
KEYを「GOOGLE_APPLICATION_CREDENTIALS」、VALUEを上記ダウンロードしたJSONファイルをコピー&ペースト
※コマンドから設定も可能です。
Goから呼べるようにする
サンプルコードは以下です。一応ローカル(1.8.1)では動きました。
実際にはAPIとしてHerokuにデプロイしているので、このコードをデプロイしたわけではありません。
注意
プロジェクトIDも環境変数に入れいています。ローカル環境では以下のようにして設定しました。
# xxxにはプロジェクトIDとダウンロードしたjsonファイルです。
export PROJECT_ID=xxxxx
export GOOGLE_APPLICATION_CREDENTIALS="$(cat xxxxxx.json)"
goのソースコードは以下です。gistにも似たのは置いています。
package main
import (
"cloud.google.com/go/bigquery"
"fmt"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
bq "google.golang.org/api/bigquery/v2"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"os"
)
func main() {
json := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
ctx := context.Background()
// project ID も環境変数に入れています。
projectID := os.Getenv("PROJECT_ID")
jwtConfig, err := google.JWTConfigFromJSON([]byte(json), bq.BigqueryScope)
if err != nil {
fmt.Printf("Json load error: %v\n", err)
}
ts := jwtConfig.TokenSource(ctx)
client, err := bigquery.NewClient(ctx, projectID, option.WithTokenSource(ts))
if err != nil {
fmt.Printf("Client create error: %v\n", err)
}
// SQL
bqSql := " select * from [zip.zip] order by zip limit 10"
fmt.Println(bqSql)
q := client.Query(bqSql)
it, err := q.Read(ctx)
if err != nil {
fmt.Printf("Error2: %v\n", err)
}
for {
var values []bigquery.Value
err := it.Next(&values)
if err == iterator.Done {
break
}
if err != nil {
fmt.Printf("Error3: %v\n", err)
}
fmt.Printf(values[0].(string))
fmt.Printf(values[1].(string))
}
}