スケジュールクエリでも最高のメタデータを付与したい人生だった

この記事は、BigQuery Advent Calendar 2021の8日目(シリーズ2)の記事です。カレンダーが人気ですでに枠が埋まっていましたが、書きたかったので勝手にシリーズ2を作りました。ちなみに12/23も書くらしいです。

みんな大好きメタデータ

皆さん、データ好きですか?! 私も好きです。実際のデータも好きですが、そのデータがどこからきて、どういう意味を持っていて...といったメタデータも大好きです。メタデータが充実していると

  • 分析に相応わしいテーブルかどうか分かる
  • 似てるカラムの意味の際が分かる
  • 分からない場合は誰に聞けばいいか(=データオーナー)が分かる

などなどのご利益があります(ない場合はとても困ります...)。データを分析する前の事前調査の時間を小さく & 分析の精度を上げてくれる側面があるため、私は大好きだし、自分でテーブル / ビューを作るときはなるべくメタデータを入れたいなと思って生活しています。

素朴なスケジュールクエリは(カラム)メタデータを吹き飛ばす

ここからはBigQuery & Terraformを使った話になります。Terraformを使うと、BigQueryのテーブル定義をコードで管理できます。テーブル自体のdescription、カラムのdescription、ラベルなどを定義できます。

このテーブルに毎日スケジュールクエリでデータを流していきたい場面を想定しましょう。例えば、こんな感じです。よくあるケースだと思います。

resource "google_bigquery_data_transfer_config" "my_scheduled_query" {
  display_name             = "これはデータウェアハウス用に変換するスケジュールクエリだよ!"
  data_source_id           = "scheduled_query"
  schedule                 = "every 1 hours"
  destination_dataset_id   = "my_dataset"
  data_refresh_window_days = 0
  disabled                 = false

  email_preferences {
    enable_failure_email = true
  }

  params = {
    destination_table_name_template = "my_table"
    write_disposition               = "WRITE_TRUNCATE"
    query                           = "SELECT * FROM ... INNER JOIN ..."
  }
}

...が、実際にこれを動かすとカラムのメタデータが吹き飛んでしまいます。メタデータがある平和な暮らしを俺はしたい!!!

DDLを組み合わせてスケジュールクエリでもメタデータを付与する

そんな感じで困っていたところ、DDLを組み合せてメタデータを付与する方法を同僚から教えてもらいました。BigQueryはクエリだけでなくDDLを書けるので、メタデータはそちらに書くという形です。

resource "google_bigquery_data_transfer_config" "my_scheduled_query" {
  display_name             = "これはデータウェアハウス用に変換するスケジュールクエリだよ!"
  data_source_id           = "scheduled_query"
  schedule                 = "every 1 hours"
  destination_dataset_id   = ""
  data_refresh_window_days = 0
  disabled                 = false

  params = {
    query = <<-EOT
      CREATE OR REPLACE TABLE
        `my-project.my_dataset.my_table`
      (
        my_column1 INTEGER OPTIONS(description = "カラム1だよ"),
        my_column2 STRING OPTIONS(description = "カラム2だよ")
      )
      OPTIONS
      (
        description = "このテーブルはデータウェアハウス構築の中でこういう文脈で使われるよ",
        labels = [
          ("owner", "my-team"),
          ("has_pii", "false"),
          ("managed_by","syou6162")
        ]
      )
      AS (
        SELECT * FROM ... INNER JOIN ...
      )
    EOT
  }

  email_preferences {
    enable_failure_email = true
  }
}

以上、メタデータでhappyなデータ活用生活を送りましょう。