以下の内容はhttps://www.yasuhisay.info/entry/2025/09/13/031319より取得しました。


dbtの実行失敗により影響を受けているダッシュボードの一覧を出す

背景 & やりたいこと

  • dbtは多くの場合、後段でBIなどのダッシュボードに接続されます
    • つまり、dbtの実行失敗はダッシュボードへの影響があることを意味します
  • dbtはDAG形式でmodelを実行していくため、失敗したとしても全て失敗するよりも部分的に失敗することが多いです
    • その場合は影響を受けるダッシュボードも一部になります
  • 実行が失敗したモデル情報を元に、影響があるダッシュボードのオーナーに素早く連絡をしたいことは多いです

前提

Tableau / Looker Studio / Connected Sheetなど、様々なダッシュボードはdbtのexposureとして登録できます。その自動化のやり方については以下を参照してください。

影響を受けているダッシュボードの一覧を出す

結論から先に。以下のコマンドで一覧をさっと出せます。uv経由でdbtを使う想定で書いていますが、そうでない人はよしなに調整してください。

# ステップ1: 失敗したモデルをの一覧を出す
cat target/run_results.json | jq -r '[.results[] | select(.status != "success") | .unique_id | split(".") | .[-1]] | map(. + "+") | join(" ")' > /tmp/models_with_plus.txt

# ステップ2: 影響を受けているexposureの一覧を出す
uv run dbt ls --select "$(cat /tmp/models_with_plus.txt)" --resource-type exposure --output json --quiet | jq -s '.' > /tmp/affected_exposures.json

# ステップ3: 連絡に必要なexposureの情報を付与する
jq -s '
  .[0] as $exposures |
  .[1].exposures as $all_exposures |

  [$exposures[] | .unique_id as $id | $all_exposures[$id] | {id: $id, name: .name, url: .url, label: .label, owner: .owner.name, email: .owner.email}]' /tmp/affected_exposures.json target/manifest.json

出力結果としては以下のようなJSONを得られます。jqでmarkdownに加工してもいいんですが、最近だとこういったところの欲しい加工についてはClaude CodeなどLLM Agentがよしなにやってくれると思うので、この情報が得られれば十分でしょう。

[
  {
    "id": "exposure.my_project.3ac3db04_7879_4c08_b37f_42dfa7b0b597",
    "name": "3ac3db04_7879_4c08_b37f_42dfa7b0b597",
    "url": "https://prod-apnortheast-a.online.tableau.com/#/site/my_site/workbooks/1026318/views",
    "label": "全社KPIダッシュボード",
    "owner": "Yasuhisa Yoshida",
    "email": "yasuhisa.yoshida@..."
  },
  {
    "id": "exposure.my_project.ece56807_e366_4c65_ad24_436270bdb29c",
    "name": "ece56807_e366_4c65_ad24_436270bdb29c",
    "url": "https://prod-apnortheast-a.online.tableau.com/#/site/my_site/workbooks/1026322/views",
    "label": "自分用の砂場ダッシュボード",
    "owner": "Yasuhisa Yoshida",
    "email": "yasuhisa.yoshida@..."
  }
]

解説

大したことはやってないですが、一応どんな感じで動いているのかを解説しておきます。

ステップ1: 失敗したモデルをの一覧を出す

このステップではモデルの一覧を出しますが

という処理をやっています。

cat target/run_results.json | jq -r '[.results[] | select(.status != "success") | .unique_id | split(".") | .[-1]] | map(. + "+") | join(" ")' > /tmp/models_with_plus.txt

ステップ2: 影響を受けているexposureの一覧を出す

ここは単純です。ステップ1の出力を使いつつ、対象をダッシュボード(exposure)に絞り込みます。

uv run dbt ls --select "$(cat /tmp/models_with_plus.txt)" --resource-type exposure --output json --quiet | jq -s '.' > /tmp/affected_exposures.json

ステップ3: 連絡に必要なexposureの情報を付与する

ここが若干ダルいところです。dbt ls --selectした結果にはexposureのURLやオーナーといった詳細な情報が載っていません。その情報はtarget/manifest.jsonに載っているため2つのJSONファイルの内容をmergeして連絡に必要な情報を取得しています。

jq -s '
  .[0] as $exposures |
  .[1].exposures as $all_exposures |

  [$exposures[] | .unique_id as $id | $all_exposures[$id] | {id: $id, name: .name, url: .url, label: .label, owner: .owner.name, email: .owner.email}]' /tmp/affected_exposures.json target/manifest.json

普段dbtを開発している人だと、jqよりもSQLのほうが伝わりやすいと思うので、↑と同じ処理をするクエリ(DuckDBで動きます)も載せておきます。

WITH
affected_exposures AS (
  SELECT unique_id
  FROM read_json('/tmp/affected_exposures.json')
),
all_exposure_details AS (
  SELECT
      key AS unique_id,
      value->>'$.name' AS name,
      value->>'$.url' AS url,
      value->>'$.label' AS label,
      value->>'$.type' AS type,
      value->>'$.description' AS description,
      value->>'$.owner.name' AS owner_name,
      value->>'$.owner.email' AS owner_email
  FROM json_each(
      (SELECT content FROM read_json('/tmp/manifest_exposures.json') AS t(content))
  )
)
SELECT
  unique_id AS id,
  name,
  url,
  label,
  type,
  owner_name,
  owner_email
FROM all_exposure_details
WHERE unique_id IN (
  SELECT unique_id
  FROM affected_exposures
)
ORDER BY unique_id;

まとめ

障害対応中は慌しいので、ステークホルダーへの連絡が後手になることもあると思いますが、こういったスクリプトも活用しながらスムーズな障害対応を目指しましょう。




以上の内容はhttps://www.yasuhisay.info/entry/2025/09/13/031319より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14