Atsushi2022の日記

データエンジニアリングに関連する記事を投稿してます

Dataplexで外部キー制約を満たしているかのデータ品質チェック

BigQueryの外部キー制約は強制適用されないため、外部キー参照先の値(またはNULLのみ)しか入らないようにユーザー側で管理する必要がある。

そこでDataplexを使用して定期的に外部キー制約に沿った値になっているか確認できないかと考えた。

調べたところ、Dataplexを使用してSQL行チェックルールを使用して、外部キー参照先の値のみになっているかどうか定期的に確認できた。

以下は、確認結果についてのメモです。

まずはテスト用に2つのテーブルを作成した。

company_listテーブルには、会社IDと会社名(name)の列が存在する。staffテーブルは、スタッフのID、名前、会社名(company_name)の列が存在する。

staffテーブルのcompany_name列が、company_listテーブルのname列を外部参照する。

  • company_listテーブル

  • staffテーブル

以下はデータセット、テーブル作成のTerraformコード。

resource "google_bigquery_dataset" "default" {
  dataset_id                  = "test_dataset"
  friendly_name               = "test"
  description                 = "This is a test description"
  location                    = "US"
  # default_table_expiration_ms = 3600000
}

resource "google_bigquery_table" "company_list" {
  dataset_id = google_bigquery_dataset.default.dataset_id
  table_id   = "company_list"

  schema = <<EOF
  [
    {
      "name": "id",
      "type": "INT64",
      "mode": "NULLABLE"
    },
    {
      "name": "name",
      "type": "STRING",
      "mode": "NULLABLE"
    }
  ]
  EOF

  table_constraints {
    primary_key {
      columns = ["name"]
    }
  }
}

resource "google_bigquery_table" "staff" {
  dataset_id = google_bigquery_dataset.default.dataset_id
  table_id   = "staff"

  schema = <<EOF
  [
    {
      "name": "id",
      "type": "INT64",
      "mode": "NULLABLE"
    },
    {
      "name": "person_name",
      "type": "STRING",
      "mode": "NULLABLE"
    },
    {
      "name": "company_name",
      "type": "STRING",
      "mode": "NULLABLE"
    }
  ]
  EOF

  table_constraints {
    foreign_keys {
      referenced_table {
        project_id  = data.google_project.project.project_id
        dataset_id  = google_bigquery_table.company_list.dataset_id
        table_id    = google_bigquery_table.company_list.table_id
      }
      column_references {
        referencing_column = "company_name"
        referenced_column = "name"
      }
    }
  }
}

さらに、Dataplexのデータ品質チェックを作成する。SQLでは、DISTINCTで会社名を参照先のテーブルを取り出して、それらの会社名のいずれかに含まれていることを確認する。

resource "google_dataplex_datascan" "check_foreign_key_staff_table" {
  location     = "us-central1"
  display_name = "Check if satisfy foreign key"
  data_scan_id = "check-foreign-key-staff-table"

  data {
    resource = "//bigquery.googleapis.com/${google_bigquery_table.staff.id}"
  }

  execution_spec {
    trigger {
      on_demand {}
    }
  }

  data_quality_spec {
    sampling_percent = 100

    rules {
      name = "check-foreign-key"
      column = "company_name"
      dimension = "CONSISTENCY"
      row_condition_expectation {
        sql_expression = <<EOL
          company_name IN (
            SELECT
              DISTINCT name
              FROM ${google_bigquery_table.company_list.project}.${google_bigquery_table.company_list.dataset_id}.${google_bigquery_table.company_list.table_id}
              -- FROM句でプロジェクト名を指定しないと、table not found的なエラーになるので要注意
          )
        EOL
      }
    }
  }
}

では、実際にデータ品質スキャンを実行して確かめる。

それぞれのテーブルには次のようなデータを入れた。

この状態でデータ品質スキャンを実行すると成功した。

次に失敗するパターンも試してみた。staffテーブルにQuad.Incというcompnany_listテーブルに存在しない会社名のレコードを挿入した。

この状態でデータ品質スキャンを実行すると想定通り失敗となった。

ちなみにstaffテーブルにレコードが0件の状態も試してみたが、想定通り成功になった。

このようにしてDataplexのデータ品質スキャンを使えば、外部キー制約を満たしていることを定期的に確認できそう。

他に外部キー制約を満たしていることを確認するための良い方法があれば、教えてください。

以上