Carpe Diem

備忘録。https://github.com/jun06t

GolangでBigQueryにデータを追加する

概要

GolangでのBigQueryの使い方です。
認証周りが以前と変わっており、JWTを使ってゴニョゴニョしてた部分をライブラリ側で吸収してくれるようになったのか使う側は簡単になりました。

環境

  • go 1.8.3

サービスアカウントキーの作成

API Console Credentials pageで以下のようにサービスアカウントキーを作成します。

f:id:quoll00:20170622010124p:plain

最低限必要な権限だけ与えます。今回はデータの追加などをするため、BigQueryのデータ編集者権限を与えます。

f:id:quoll00:20170622010057p:plain

ちなみに権限は以下のように決まってます。

f:id:quoll00:20170622002755p:plain ref: アクセス制御

クエリを叩きたい場合はユーザ権限。データの追加をしたい場合はデータ編集者権限となります。

鍵の種類はJSONP12の2種類から選べますが、推奨されているのはJSONの方です。

設定すると以下のような鍵がダウンロードされます。1度しかダウンロードできないので大切に保管してください。

{
  "type": "service_account",
  "project_id": "sample-project",
  "private_key_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----\nM~~dummy~~TJLEi4HT\n-----END PRIVATE KEY-----\n",
  "client_email": "sample-api@sample-project.iam.gserviceaccount.com",
  "client_id": "10xxxxxxxxxxxxxxxxxxxxx",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/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/sample-api%40sample-project.iam.gserviceaccount.com"
}

認証

アプリケーションのデフォルト認証情報の仕組みにありますが、以下の認証方法あります。

  1. 環境変数GOOGLE_APPLICATION_CREDENTIALSが設定されていたらそのファイルをcredentialsとして使う
  2. Google Cloud SDKをインストールして、$ gcloud auth application-default loginを実行する(ローカル環境で推奨)
  3. Google App Engineで実行していればそのサービスアカウントを使う
  4. Google Compute Engineで実行していればそのサービスアカウントを使う
  5. 上記のどれにも当てはまらなければエラー

今回は環境変数を使ったやり方で実行します。

サンプルコード

データをBigQueryに追加するコードです。
datasetやtableはあらかじめ作成しています。

type Item struct {
    Timestamp time.Time `bigquery:"timestamp"`
    UserID    string    `bigquery:"user_id"`
    Param     string    `bigquery:"param"`
}

func Put(userID string, param string) error {
    ctx := context.Background()
    client, err := bigquery.NewClient(ctx, "sample-project")
    if err != nil {
        return err
    }
    defer client.Close()

    u := client.Dataset("dataset-name").Table("table-name").Uploader()
    now := time.Now()
    items := []*Item{
        {Timestamp: now, UserID: userID, Param: param},
    }
    err = u.Put(ctx, items)
    if err != nil {
        return err
    }

    return nil
}

動作検証

環境変数を設定します。

$ export GOOGLE_APPLICATION_CREDENTIALS=./key.json

先程のメソッドが入ったプログラムを実行すると、以下のようなデータが取得できました。

f:id:quoll00:20170622005735p:plain

ソース