Meguro.es #17 @ Drecom
2018年10月4日
自己紹介
ちきさん
GitHub/Twitter/Qiita: @ovrmrw
市ヶ谷のオプトという会社で働いています
(話すこと)
BigQueryのクエリ結果がデカいときに簡単にローカルにダウンロードする方法
BigQuery は Web UI で使いたいじゃないですか
Web UI を使うメリット・デメリット
-
メリット
- クエリを書いてすぐに実行できるのでさくさく試せる。
- クエリを保存する機能が便利。
- エンジニアじゃなくても使える。例えばビジネスの人とか。
-
デメリット
- 16000行を超える結果を簡単にダウンロードできない。
16000行で切られてしまう選択肢
- JSON としてダウンロード
- CSV 形式でダウンロード
- スプレッドシートに保存
たとえクエリ結果が100万行でも勝手に切られてしまう。かなしい。
かなしい例
ではどうすればいいのか
- クエリ結果を別テーブルに保存
- テーブルをCSVとしてGCSにエクスポート
- GCSからダウンロード
何が問題なのか
- とてもめんどくさい
- 10パターンぐらいこの流れをやるとうんざりする
- テーブル作成やGCSのファイル作成権限を作業者に付与する必要がある
BigQueryのリードオンリー権限のみでデカい結果をダウンロードしたい!
なので TypeScript で書いた
概要
BigQuery
のインスタンスを生成する。
import * as BigQuery from '@google-cloud/bigquery';
const bigquery = new BigQuery();
createQueryJob()
メソッドで Job を生成する。
const job = await bigquery.createQueryJob(queryOption).then(data => {
const [job, apiResponse] = data;
return job;
});
Job の getQueryResults()
メソッドで結果を取得する。全件取得するまで繰り返す。
let option = { location: 'US', maxResults: 5000 };
const fileWriter = new FileWriter();
do {
const [rows, _option] = await job.getQueryResults(option);
option = _option;
rows.forEach(row => {
fileWriter.writeRow(row); // 最終的にWriteStreamのwriteメソッドに渡している。
});
} while (option);
実行前に概算コストを表示するので思わぬ課金を防げるぞ
statistics: {
"計算MB": 34.02571105957031,
"計算GB": 0.03322823345661163,
"キャッシュヒット": false,
"コスト(円)": 0.01833393740525935
}
!! The query will be executed after 5 seconds...
まとめ
- Web UI を使うとデカい結果をダウンロードするのはとてもめんどくさい。
- API を叩いてダウンロードしよう。
- ダウンロードは複数回に分けて、ファイルへの書き込みはストリームを使おう。
- ストリームと RxJS を組み合わせるととっても簡単だ。