BigQuery から dbt のインクリメンタルモデルが突然消えた原因と解決方法
BigQuery から dbt のインクリメンタルモデルが突然消えた原因と解決方法
はじめに
BigQuery から dbt のインクリメンタルモデルが突然消えて、原因を突き止めるのに時間がかかったので、原因と解決方法をまとめました。
実行環境
- BigQuery
- dbt-core:- 1.8.2
エラー
BigQuery で設定していた 課金される最大バイト数 の上限に達して、ジョブが失敗した。
通常だと、インクリメンタルモデル は増分更新のため、上限に引っかかることはない。
結果をよく見ると、インクリメンタルモデル を新規作成しようとしていることがわかり、
元の インクリメンタルモデル が消えていることに気づいた。
HH:MM:SS    Database Error in model rpt_sample_model (models/reporting/ga4/rpt_sample_model.sql)
  Query exceeded limit for bytes billed: 3221225416800. 9999999999999 or higher required.
  compiled Code at target/run/dbt_project_name/models/reporting/ga4/rpt_sample_model.sql
原因
モデルを作成してから 168 時間後に消えるように テーブルの有効期限 を設定していた。
インクリメンタルモデル は、増分更新で テーブルの作成日時 は更新されないため、168 時間後に削除された。
毎日エラーが発生するわけではないので、原因を特定するのに時間がかかった。
dbt_project.yml
dbt_project.yml で hours_to_expiration を設定していた。
略
models:
  dbt_project_name:
    +hours_to_expiration: 168
略
解決方法
- 消えたテーブルの復元
- 今日の定期実行分の処理を実行
- テーブルの有効期限を- 常にオフに設定
消えたテーブルの復元
BigQueryで削除してしまったテーブル・データセットは復元できる! | クラウドテクノロジーブログ | ソフトバンク を参考にテーブルを復元した。
削除直前の時間を下記クエリで取得。
select unix_millis(timestamp_sub(current_timestamp(), interval 3 hour))
取得した時間(1726531456789)を指定して、テーブルを復元。
$ bq cp project_name_prod_reporting.rpt_sample_model@1726531456789 project_name_prod_reporting.rpt_sample_model
今日の定期実行分の処理を実行
復元後、定期実行の処理を再度実行。
$ dbt run -s +rpt_sample_model
テーブルの有効期限 を 常にオフ に設定
既存のテーブルについては、bq コマンドで直接変更
テーブルを管理する | BigQuery | Google Cloud
テーブルのデフォルトの存続期間(秒)です。最小値は 3,600 秒(1 時間)です。 現在時刻にこの整数値を足した値が有効期限になります。 0 を指定すると、テーブルの有効期限が削除され、テーブルは無期限に有効になります。 有効期限のないテーブルは手動で削除する必要があります。
下記を実行して、テーブルの有効期限 を 常にオフ に変更。
$ bq update --expiration 0 project_id:dataset_name.rpt_sample_model

今後発生しないように dbt のモデルの設定も変更
models/reporting/ga4/rpt_sample_model.sql で、
dbt_project.yml で設定していた hours_to_expiration の値を上書き。
  {{
    config(
      materialized='incremental'
      , incremental_strategy='insert_overwrite'
+     , hours_to_expiration=none
    )
  }}
* hours_to_expiration に 'none', 0, '0' を設定するとエラーが発生しました
hours_to_expiration の設定方法に詰まったときに試した設定方法
hours_to_expiration=none を設定するのが正しい
BigQuery configurations | dbt Developer Hub
Parameter | Type | Required | Default | Change Monitoring Support -- | -- | -- | -- | -- hours_to_expiration |
<integer>| no |none| alter
dbt のドキュメントに設定方法がしっかり記載されていた。
$ dbt run -s rpt_sample_model
HH:MM:SS  Running with dbt=1.8.3
HH:MM:SS  Registered adapter: bigquery=1.8.2
HH:MM:SS  Found 999 models, 99 seeds, 9999 data tests, 999 sources, 99 exposures, 999 macros
HH:MM:SS
HH:MM:SS  Concurrency: 4 threads (target='dev')
HH:MM:SS
HH:MM:SS  1 of 1 START sql incremental model project_name_dev_reporting.rpt_sample_model  [RUN]
HH:MM:SS  1 of 1 OK created sql incremental model project_name_dev_reporting.rpt_sample_model  [CREATE TABLE (33.6k rows, 192.2 MiB processed) in 7.96s]
HH:MM:SS
HH:MM:SS  Finished running 1 incremental model in 0 hours 0 minutes and 11.90 seconds (11.90s).
HH:MM:SS
HH:MM:SS  Completed successfully
HH:MM:SS
HH:MM:SS  Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1
hours_to_expiration='none' は、エラーが発生
$ dbt run -s rpt_sample_model
HH:MM:SS  Running with dbt=1.8.3
HH:MM:SS  Registered adapter: bigquery=1.8.2
HH:MM:SS  Found 999 models, 99 seeds, 9999 data tests, 999 sources, 99 exposures, 999 macros
HH:MM:SS
HH:MM:SS  Concurrency: 4 threads (target='dev')
HH:MM:SS
HH:MM:SS  1 of 1 START sql incremental model project_name_dev_reporting.rpt_sample_model  [RUN]
HH:MM:SS  BigQuery adapter: https://console.cloud.google.com/bigquery?project=project-name-dev&j=bq:asia-northeast1:0x0x0x0x-0x0x-0x0x-0x0x-0x0x0x0x0x0x&page=queryresults
HH:MM:SS  1 of 1 ERROR creating sql incremental model project_name_dev_reporting.rpt_sample_model  [ERROR in 1.54s]
HH:MM:SS
HH:MM:SS  Finished running 1 incremental model in 0 hours 0 minutes and 4.50 seconds (4.50s).
HH:MM:SS
HH:MM:SS  Completed with 1 error and 0 warnings:
HH:MM:SS
HH:MM:SS    Database Error in model rpt_sample_model (models/reporting/ga4/rpt_sample_model.sql)
  Unrecognized name: none; failed to set 'expiration_timestamp' in OPTIONS() at [12:72]
  compiled Code at target/run/dbt_project_name/models/reporting/ga4/rpt_sample_model.sql
HH:MM:SS
HH:MM:SS  Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1
hours_to_expiration=0 もエラーが発生
テーブルを管理する | BigQuery | Google Cloud
テーブルのデフォルトの存続期間(秒)です。最小値は 3,600 秒(1 時間)です。現在時刻にこの整数値を足した値が有効期限になります。0 を指定すると、テーブルの有効期限が削除され、テーブルは無期限に有効になります。有効期限のないテーブルは手動で削除する必要があります。
これを読んで、0 を設定すればよいと思ってしまった・・・
hours_to_expiration='0' も hours_to_expiration=0 と同じエラーが発生する。
$ dbt run -s rpt_sample_model
HH:MM:SS  Running with dbt=1.8.3
HH:MM:SS  Registered adapter: bigquery=1.8.2
HH:MM:SS  Found 999 models, 99 seeds, 9999 data tests, 999 sources, 99 exposures, 999 macros
HH:MM:SS
HH:MM:SS  Concurrency: 4 threads (target='dev')
HH:MM:SS
HH:MM:SS  1 of 1 START sql incremental model project_name_dev_reporting.rpt_sample_model  [RUN]
HH:MM:SS  Unhandled error while executing target/run/dbt_project_name/models/reporting/ga4/rpt_sample_model.sql
404 GET https://bigquery.googleapis.com/bigquery/v2/projects/project-name-dev/datasets/project_name_dev_reporting/tables/rpt_sample_model?prettyPrint=false: Not found: Table project-name-dev:project_name_dev_reporting.rpt_sample_model
HH:MM:SS  1 of 1 ERROR creating sql incremental model project_name_dev_reporting.rpt_sample_model  [ERROR in 6.13s]
HH:MM:SS
HH:MM:SS  Finished running 1 incremental model in 0 hours 0 minutes and 8.62 seconds (8.62s).
HH:MM:SS
HH:MM:SS  Completed with 1 error and 0 warnings:
HH:MM:SS
HH:MM:SS    404 GET https://bigquery.googleapis.com/bigquery/v2/projects/project-name-dev/datasets/project_name_dev_reporting/tables/rpt_sample_model?prettyPrint=false: Not found: Table project-name-dev:project_name_dev_reporting.rpt_sample_model
HH:MM:SS
HH:MM:SS  Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1
https://bigquery.googleapis.com/bigquery/v2/projects/project-name-dev/datasets/project_name_dev_reporting/tables/rpt_sample_model?prettyPrint=false
にアクセスすると、下記エラーが表示される。
このエラーを修正しようといろいろ試して、無駄に時間を使ってしまった。
{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "CREDENTIALS_MISSING",
        "domain": "googleapis.com",
        "metadata": {
          "method": "google.cloud.bigquery.v2.TableService.GetTable",
          "service": "bigquery.googleapis.com"
        }
      }
    ]
  }
}
まとめ
テーブルの有効期限 を過ぎると、BigQuery からテーブルが消えてしまいます。
インクリメンタルモデル は、増分更新のため テーブルの作成日時 は更新されません。
インクリメンタルモデル には、hours_to_expiration=none を設定して、
テーブルの有効期限 を 常にオフ にすることで、削除されないようにしておきましょう。

