BigQueryのスケジュールクエリ機能を使うと定期的にクエリを実行できます。
Cloud Composerなどのワークフローツールのセットアップが不要なため、気軽にクエリを定期実行したい場合には便利です。
しかし、その手軽さゆえに「野良」のスケジュールクエリが散見されることもよくあるので、terraformを使って管理してみます。
クエリを格納するディレクトリ構造は以下のようにします。
scheduled_queries
├── 実行スケジュール1
│ │── データセット名1
│ │ ├── テーブル名1.sql
│ │ └── テーブル名2.sql
│ ├── データセット名2
│ │ └── テーブル名3.sql
│ └── データセット名3
│ └── テーブル名4.sql
└── 実行スケジュール2
└── データセット名4
└── テーブル名5.sql
実行スケジュール部分は every_1_hours
や every_day_0400
のようなAppEngineのスケジュール書式を指定します。
そのまま指定すると空白やコロンなどのファイルシステム的に問題のある記号も含まれているので、以下のように変換しておきます。
- 半角空白 (
_
) - コロン (
:
) → 削除
そして以下のようなterraformを書くとSQLファイルを増やすとそれに連動してスケジュールクエリが登録されるようになります。
# ref: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/bigquery_data_transfer_config#example-usage---bigquerydatatransfer-config-scheduled-query
resource "google_project_iam_member" "datatransfer_permission" {
project = local.project
role = "roles/iam.serviceAccountShortTermTokenMinter"
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-bigquerydatatransfer.iam.gserviceaccount.com"
}
resource "google_bigquery_data_transfer_config" "scheduled_queries_1hour" {
depends_on = [google_project_iam_member.datatransfer_permission]
for_each = fileset("${path.module}/scheduled_queries", "*/*/*.sql")
project = local.project
display_name = trimsuffix(each.value, ".sql")
location = "US"
data_source_id = "scheduled_query"
schedule = replace(replace(split("/", each.value)[1], "_", " "), "/(\\d{2})(\\d{2})/", "$1:$2")
destination_dataset_id = split("/", each.value)[2]
params = {
destination_table_name_template = trimsuffix(split("/", each.value)[3], ".sql")
write_disposition = "WRITE_TRUNCATE"
query = file("${path.module}/scheduled_queries/${each.value}")
}
}