はじめに
みなさんGoogleのBigQuery使ってますか?とても便利なのでこちらの記事でも紹介させて頂いたように弊社でもほぼ全てのデータをBigQueryに入れて分析しています。
RubyからBigQueryを扱うGemは以前からいくつか存在しているのですが、現状の最新(2017年1月時点)ではどう扱うのが一番良いのかをまとめておきます。
BigQueryを扱えるGem達
abronte/BigQuery
Googleで検索すると一番上に出てくるのでこのGemを利用している人も多いと思います。
しかし、2016年になってからあまりメンテされている様子はありませんので、利用は控えたほうが良いでしょう。
google/google-api-client-ruby
こちらのGoogleが提供しているgoogle-api-client-rubyを最新版にしてBigQueryのインターフェースを直接利用することも出来ますが、ドキュメントもサンプルコードもほぼありませんので、ソースをひたすら読んで実装する必要があります。あまりおすすめできません。
GoogleCloudPlatform/google-cloud-rubyを使う(推奨)
実はGoogleがBigQueryを扱うためのGemgoogle-cloud-bigquery
を半年ぐらい前にリリースしてくれています。(google-api-clientとは別に)
GoogleのCloud関連のAPIを呼ぶためのgoogle-cloud
というGemの一部です。
gem install google-cloud-bigquery
こちらは公式ドキュメントやサンプルコードも全て用意されています。
そしてgoogle-api-clientも最新のバージョンに対応しています。
こちらのGemのほうが極めてシンプルですし、Googleもこちらの利用を推奨しています。
google-cloud-bigqueryを用いたサンプルコード
同期的にデータを取得する
結果のサイズが10MB以下であればこちらで取得できます。
require "google/cloud/bigquery"
bigquery = Google::Cloud::Bigquery.new(
project: "test-project", #BigQueryのプロジェクトID
keyfile: "./auth.json" #認証用JSONキーファイル
)
sql = "select id from app.items limit 1000"
data = bigquery.query sql
puts data.count
data.each do |row|
puts row["id"]
end
非同期でデータを取得する
クエリの実行に時間がかかる場合などはこちらを利用しましょう。
require "google/cloud/bigquery"
bigquery = Google::Cloud::Bigquery.new(
project: "test-project",
keyfile: "./auth.json"
)
job = bigquery.query_job sql
job.wait_until_done!
unless job.failed?
puts job.query_results.size
job.query_results.each do |row|
puts row["id"]
end
end
めんどくさい処理は必要ありません、非常にシンプルでわかりやすいインターフェースになっています。
大きい結果サイズを扱う場合
query_job
の引数にlarge_results:true
やtable
を設定する必要があります。(この場合はtable名
ではなくtableオブジェクト
なので注意)
dataset = bigquery.dataset "tmp"
result_table = dataset.create_table "results"
sql = "SELECT id from app.items limit 110001"
job = bigquery.query_job(sql, table: result_table, write: 'truncate', large_results: true)
StandardSQL対応は?
google-cloud-ruby
も丁度先月@yancyaさんのコミットがマージされたことにより、Standard SQLのサポートがされたので、Standard SQLを利用することができます。
sql = "select FORMAT_TIMESTAMP('%Y-%m-%d %H-%M-%S', CURRENT_TIMESTAMP, 'Asia/Tokyo') as t"
data = bigquery.query sql, legacy_sql: false #use_legacy_sqlでないことに注意
puts data
まとめ
RubyからシンプルにBigQueryを扱いたい場合はgoogle-cloud-bigquery
を利用しましょう。