dbq(CLI tool to easily Decorate BigQuery table name)を作ってみた


  • Go 言語製
  • BigQuery にクエリ投げるときに簡単にデコレータをつけられるラッパーツール

BigQuery の課金仕様と注意点をまとめてみた(2015-07 時点) - Qiita に書いたとおり、BigQuery の検索費用は、テーブルデコレータを使えば節約できますが、bq コマンドでアドホックに実施するには使いづらいところがあります

  • 数時間前までの指定くらいなら自力でも計算できるが、開始日時から終了日時の Unixtime を計算するのは面倒
  • さらにタイムゾーン込みで計算するのも面倒
  • ドライランで確認できるバイト数(6862860066238 bytes of data など)からどれくらいコストがかかるのかを計算するのも面倒

ということで、bq query コマンドをラップする CLI ツールを作ってみました

# ドライラン
# この例では 2015-07-20 00:00:00 JST から現在までのデータを走査対象とする
# デコレータがない場合とある場合の走査バイト数と費用の比較も表示する
$ dbq query "SELECT * FROM [mtburnlog.foo@] ORDER BY time LIMIT 1" --startDate="2015-07-20 00:00:00" --tz="-9" --dryRun
Raw: SELECT * FROM [mtburnlog.foo] ORDER BY time LIMIT 1
Query successfully validated. Assuming the tables are not modified, running this query will process 6862860066238 bytes of data.

- 6862860066238 bytes equal to 6,862,860,066,238 bytes
- 6862860066238 bytes equal to 6.2TiB
- 6862860066238 bytes equal to $31.20867 (= 6.24173 TiB * $5)

Decorated: SELECT * FROM [mtburnlog.foo@1437314400000-] ORDER BY time LIMIT 1
Query successfully validated. Assuming the tables are not modified, running this query will process 109495551638 bytes of data.

- 109495551638 bytes equal to 109,495,551,638 bytes
- 109495551638 bytes equal to 102GiB
- 109495551638 bytes equal to $0.49793 (= 0.09959 TiB * $5)

# クエリを発行する
# 見やすさのためカラムを限定する
# Decorated: 以下が実際に発行されるクエリ
$ dbq query "SELECT time, bar, baz FROM [mtburnlog.foo@] ORDER BY time LIMIT 1" --startDate="2015-07-20 00:00:00" --tz="-9"
Decorated: SELECT time, bar, baz FROM [mtburnlog.foo@1437314400000-] ORDER BY time LIMIT 1
Waiting on bqjob_r232f2e05c1289cfb_0000014eb43d27e4_1 ... (1s) Current status: DONE    
+---------------------+-------+----------+
|        time         | bar | baz |
+---------------------+-------+----------+
| 2015-07-19 13:42:54 | 934   |      594 |
+---------------------+-------+----------+

ついでに、DATE_ADD('datetime', -9, 'HOUR')も置換するプレースホルダーを用意しました

  • WHERE で JST の時間を指定したいことが多いので
# _tz(日時) が置換されるプレースホルダー
$ dbq query "SELECT time, bar, baz FROM [mtburnlog.foo@] WHERE _tz(2015-07-20 01:00:00) <= time and time <= _tz(2015-07-20 02:00:00) ORDER BY time LIMIT 1" --startDate="2015-07-20 00:00:00" --tz="-9"
Decorated: SELECT time, bar, baz FROM [mtburnlog.foo@1437314400000-] WHERE DATE_ADD('2015-07-20 01:00:00', -9, 'HOUR') <= time and time <= DATE_ADD('2015-07-20 02:00:00', -9, 'HOUR') ORDER BY time LIMIT 1
Waiting on bqjob_r7943732b00690112_0000014eb442afdc_1 ... (3s) Current status: DONE    
+---------------------+-------+----------+
|        time         | foo | baz |
+---------------------+-------+----------+
| 2015-07-19 16:00:00 | 17473 |     1068 |
+---------------------+-------+----------+

補足

dbq をつくるときに使った依存パッケージなどは http://go-talks.appspot.com/github.com/yoheimuta/talks/go-intro.slide#49 にまとめました

  • Go 言語を使ったコマンドラインツールをはじめてつくる人には参考になると思います