LoginSignup
5
3

More than 5 years have passed since last update.

16000行の壁を超えてさくっとダウンロードしたい (BigQueryの話)

Last updated at Posted at 2018-10-04
1 / 19

Meguro.es #17 @ Drecom

2018年10月4日


自己紹介

ちきさん

GitHub/Twitter/Qiita: @ovrmrw

市ヶ谷のオプトという会社で働いています

3a2512bb-aa72-4515-af42-1f1721252f39.jpg


(話すこと)

BigQueryのクエリ結果がデカいときに簡単にローカルにダウンロードする方法


BigQuery は Web UI で使いたいじゃないですか


Web UI を使うメリット・デメリット

  • メリット

    • クエリを書いてすぐに実行できるのでさくさく試せる。
    • クエリを保存する機能が便利。
    • エンジニアじゃなくても使える。例えばビジネスの人とか。
  • デメリット

    • 16000行を超える結果を簡単にダウンロードできない。

16000行で切られてしまう選択肢

  • JSON としてダウンロード
  • CSV 形式でダウンロード
  • スプレッドシートに保存

たとえクエリ結果が100万行でも勝手に切られてしまう。かなしい。


かなしい例


ではどうすればいいのか

  1. クエリ結果を別テーブルに保存
  2. テーブルをCSVとしてGCSにエクスポート
  3. 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 を組み合わせるととっても簡単だ。

Thanks! :raised_hands:

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3