👋
BigQueryのクエリ結果を、Google Cloud Storage にCSVとして出力する
やりたいこと
- テーブルデータを Cloud Storage にエクスポートするにあるようなことを、Cloud Run の Node.js でやりたい。
- ただし公式によると、一つのファイルに1GBまでしか出力できず、その場合には複数ファイルに分割して出力する必要がある。
- Node.js の bigquery クライントを使って、どうやってそれを実現するのかのソースが見つからなかったので、自分で書いた。
やり方
1. BigQuery のテーブルを、CSVに全部出力
import { BigQuery } from '@google-cloud/bigquery'
import fs from 'fs'
import path from 'path'
const bigquery = new BigQuery()
/**
* データの集計を行う
*
* 使用上、集計結果を上書きすることができないため、もし集計結果を上書きしたい場合は、
* 前もって該当の latestAggregatedPeriodId を持つデータ群を削除しておく必要がある
*
* DELETE FROM \`${PROJECT_ID}.${DATASET_ID}.${TABLE_ID}\`
* WHERE latestAggregatedPeriodId = '${jsonData.latestAggregatedPeriodId}'
*/
const main = async () => {
try {
console.time('export-csv')
// SQLファイルを読み込む
const sqlPath = path.join(__dirname, 'sample.sql')
const sqlQuery = fs.readFileSync(sqlPath, 'utf-8')
const options = {
query: sqlQuery,
location: 'asia-northeast1',
destinationTable: {
projectId: PROJECT_ID,
datasetId: DATASET_ID,
tableId: TABLE_ID,
},
// 書き込みモードを指定 (WRITE_TRUNCATE, WRITE_APPEND, WRITE_EMPTY)
// 毎回新しく書き直す
writeDisposition: 'WRITE_TRUNCATE',
}
const [job] = await bigquery.createQueryJob(options)
console.log(`Job ${job.id} started.`)
// ジョブが完了するまで待つ
await job.promise()
console.log(`Job ${job.id} completed.`)
const [extractJob] = await bigquery
.dataset(DATASET_ID)
.table(VOTER_POINT_AGGREGATION_TABLE_ID)
.extract(admin.storage().bucket('bucket-name').file('sample-*.csv'), {
location: 'asia-northeast1',
format: 'CSV',
})
console.log(`Extract Job ${extractJob.id} created.`)
console.timeEnd('export-csv')
} catch (e) {
console.error('Error', e)
}
}
main()
2. BigQuery のテーブルのクエリ結果(データの一部)を CSVに出力
- EXPORT DATA を使う
EXPORT DATA
OPTIONS(
uri='gs://bucket-name/sample-*.csv',
format='CSV',
header=true,
overwrite=true) AS
SELECT
*
FROM `project-id.dataset-id.table-id`;
Discussion