Node.js で JSON データを BigQuery にインポートする
吉川@広島です。
掲題の通り、 Node.js で JSON データを BigQuery にインポートする検証をしてみましたので共有します。
本記事の実施にあたり、
BigQuery に JSON 形式のファイルデータをロードする場合の挙動や制限事項を確認してみた
こちらのブログを大いに参考にさせて頂きました。ありがとうございます。
環境
- Node.js 14.13.0
- TypeScript 4.1.3
- dotenv 8.2.0
- @google-cloud/bigquery 5.6.0
データセットの作成
GCP メニューから BigQuery を選択し開きます。
本記事の目標はテーブルを作成しそこにデータを保存することですが、その前に BigQuery のデータセットというリソースを作成する必要があります。
プロジェクト > データセット > テーブル のような階層構造になっており、データセットの位置づけは MySQL でいう Database に近いのかな、と思いました。
プロジェクト名の右にあるハンバーガーを押下して、「データセットを作成」を選択します。
データセット ID に任意の命名をします。今回は sample_dataset
としました。入力したら「データセットを作成」ボタンを押下します。
これで作成できました。プロジェクトにぶら下がるデータセット一覧を見ると sample_dataset
が追加されたことが確認できます。
サービスアカウントとキーの作成
GCP に慣れていないのでサービスアカウント周りの設定も備忘録を兼ねて記述します。
ローカル端末のプログラムから GCP リソースにアクセスするためにサービスアカウントを作成します。
まず、 IAM と管理 > サービスアカウント から 「サービスアカウントを作成」を押下します。
すると作成画面が開かれますので、任意のサービスアカウント名を入力し「作成」を押下します。
続いて「このサービスアカウントにプロジェクトへのアクセスを許可する」が開かれます。「ロールを選択」を押下するとロールを検索できるメニューが出ますので、検索欄に bigquery
と入力します。そうすると「 BigQuery 管理者」というロールが出てくるので、今回はこれを紐付けます。
ロールを選択できたら「続行」を押下し、そのまま「完了」を押下します。
これでサービスアカウント作成は完了です。
IAM と管理 > サービスアカウント に戻ると、今回追加したサービスアカウントが確認できます。
次はキーを作成します。作成したサービスアカウントのハンバーガーアイコンを押下するとメニューが出てくるので、「鍵を管理」を選択します。
画面遷移するので、「鍵を追加」を押下し、「新しい鍵を追加」を選択します。
ポップアップが出てきますので、そのまま「作成」を押下します。
作成後、すぐにキーがダウンロードされます。機密情報ですので公開しないよう注意して扱いましょう。
TypeScript コードを書く
先程のキーをスクリプトファイルと同じ場所に配置します。繰り返しになりますが、間違って GitHub の公開リポジトリにアップロードするなどないように注意しましょう。
認証のスタートガイドによると、環境変数 GOOGLE_APPLICATION_CREDENTIALS
にキーファイルの場所を指定すると読んでくれるようです。今回は dotenv ライブラリを使って環境変数をセットするので、下のような .env
ファイルを作成しておきます。
# .env GOOGLE_APPLICATION_CREDENTIALS="./my-sa-key.json"
Node.js から BigQuery へのアクセスは nodejs-bigquery を使います。以下の公式サンプルコードが参考になりました。
https://github.com/googleapis/nodejs-bigquery/blob/master/samples/loadLocalFile.js https://github.com/googleapis/nodejs-bigquery/blob/master/samples/loadJSONFromGCSAutodetect.js
また、 BiqQuery にインポートするテストデータを用意する必要があります。冒頭紹介の記事でも述べられていますが、
JSONL( LDJSON )じゃないとだめ
ということで、以下のような JSONL (JSON Lines) 形式のテキストファイルを作成しておきます。
// sample-data.jsonl { "id": 1, "name": "foo" } { "id": 2, "name": "bar" } { "id": 3, "name": "baz" }
そして実行する TypeScript コードが以下です。
import { BigQuery, JobLoadMetadata } from '@google-cloud/bigquery' import * as dotenv from 'dotenv' const main = async () => { dotenv.config() const bigQueryClient = new BigQuery() const metadata: JobLoadMetadata = { sourceFormat: 'NEWLINE_DELIMITED_JSON', autodetect: true, // スキーマ定義を autodetect する location: 'US', } const datasetId = 'sample_dataset' // 作成したデータセット名を指定 const tableId = 'sample_table' // 作成されるテーブル名を指定 (命名は任意) const [job] = await bigQueryClient .dataset(datasetId) .table(tableId) .load('./sample-data.jsonl', metadata) // 読み込む対象のファイル場所を指定 console.log(`Job ${job.id} completed.`) } main()
実行後、 BigQuery コンソールからデータセット下に新しくできたテーブルを選択し、「プレビュー」を押下すると、ちゃんとデータが入っていることがわかります。
まとめ
GCP はあまり経験がなく、手探り気味の検証となりましたが良い勉強になりました。スキーマを autodetect してインポートできるのは非常に楽ですね。