のぶLab.

流しのソフトウェアエンジニアの雑記帳. Android, Scala, Clojure, Ruby on Railsなど

ActiveRecordでBigqueryを使ってみる

目的

メインDB + Bigqueryの複数DBなRailsアプリケーションでActiveRecordからBigqueryにあるテーブルを参照するまでの手順。

前提として、Bigquery上のtable, recordの作成などは行っていることとします。

ここではローカル環境や外部サーバ上のRailsアプリケーションからそのテーブルを参照できるようにしていきます。

GCP Projectの作成

ここからGoogle Cloud Platformのプロジェクトを作成する

https://console.developers.google.com/project

クライアントIDの作成

  1. 作成したprojectを選択し、"APIと認証" > "認証情報"を選択する
  2. "新しいクライアントIDを作成"を押すとクライアントID作成用のポップアップが表示される
  3. "アプリケーションの種類"に"サービスアカウント"を選択
  4. "キーのタイプ"に"P12 key"を選択
  5. この状態でIDを作成
  6. IDが作成されたら秘密キーのパスワードが表示されるので控えておく(これはあとで使う)
  7. p12ファイルがダウンロードされる(これもあとで使う)
  8. サービスアカウントに新しいクライアントIDが作成されていることを確認
  9. 同時にメールアドレスも作成されていることも確認(これもあとで使う)

Gemのインストール

ActiveRecordでBigqueryを使うためのGemにBigBrodaというものがあるので、それを使う

michelson/BigBroda · GitHub

Gemfileにgem "bigbroda"を追加して$ bundle install

RailsからBigqueryに接続する

設定ファイルの生成

Gemをインストール後、bigqueryの設定ファイルをインストールします

rails g google_bigquery:install

これで config/initializers 配下にbigqueryに接続するための設定ファイル(bigquery.rb)が追加されます

p12ファイルを配置

先ほど作成したp12ファイルをRailsプロジェクト内の適当な場所(config内など)に移動させておいてください

bigquery.rbを編集

bigquery.rbを以下のように編集してください

GoogleBigquery::Config.setup do |config|
  config.pass_phrase = ["pass_phrase"] # クライアントIDを作成した際に表示された秘密キーのパスワード
  config.key_file    = ["key_file"] # p12ファイルのpath
  config.scope       = "https://www.googleapis.com/auth/bigquery"
  config.email       = ["email"] # クライアントIDを作成した際に一緒に作成されたEmailアドレス
  config.retries     = [retries] # 任意のretryカウント
end

config/apprication.rbの編集

RailsアプリケーションがBigBrodaを認識するようapprication.rbに以下を追加します

Bundler.require(*Rails.groups)
require "google_bigquery" # これを追加

database.ymlの編集

database.ymlにbigqueryへの接続情報を追加します

bigquery:
  database: 'DATABASE_NAME'
  adapter: 'bigquery'
  project: API_PROJECT_ID

Modelの作成

bigquery用のmodelを作成します

ここではbigquery上に'users'というテーブルがある想定でmodelを作成します

class User < ActiveRecord::Base
  establish_bq_connection "bigquery"
end

これで準備OK

確認

pry-railsが使えるという前提で、REPLで確認してみます

$ rails c
[12] pry(main)> User.all.pluck(:id)
   (3176.0ms)  SELECT testdata.users.id FROM testdata.users
=> ["1", "2"]

ちゃんと結果が取得できたらOKです!