Tableauからdbt Sematic Layerを介してMetricsを参照してみた #Tableau #dbt

2023.01.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

さがらです。

Tableauからdbt Sematic Layerを介してMetricsを参照してみたので、その内容をまとめてみます。

2023年10月29日追記

本記事の内容は古くなっており、すでに使えない仕様となっています。

最新のMetricsの定義方法、dbt Semantic LayerをTableauから参照する方法、については下記の記事をご覧ください。

dbt Semantic Layerとは

dbt Semantic Layerとは、データを用いたビジネス指標の定義について一元管理し、BIツールやデータカタログなど外部のツールから参照することで、組織内で統一された定義の元に各ビジネス指標を使用したレポート作成やデータ分析が行うことが出来る機能です。 (下図は公式Docからの引用です。)

まず前提としてdbtには「Metrics」という機能があり、売上や利益、アクティブユーザー数など、ビジネスを推進する上で定義が間違っては行けない指標について、dbt上で定義を明示化しておくことが出来ます。(※Metricsについては、こちらの記事で試しています。)

そして、dbt Cloudの場合には定義したMetricsを外部ツールから参照させるための仕組みとして、dbt Server、SQL Proxy、Metadata APIという構成要素から成り立つSemantic Layerを提供しています。

これにより、外部ツールからMetricsを参照することで、誰もが同じ定義の元に各指標を用いたレポート作成やデータ分析を行うことが出来るようになります。

下図は公式Docからの引用となりますが、dbt Semantic Layerを構成する各要素の関係性を示しております。

注意事項

2023年1月29日時点、Semantic Layerはパブリックプレビューでの提供であり、以下の条件をみたす場合のみ使用できるためご注意ください。

  • 北米でホストされているマルチテナントのdbt Cloudアカウントであること
  • 接続先のDWHは「Snowflake」であること
  • 対象のdbt projectにおいて、Develop Enviornment、Deployment Environment、ともにdbtはver1.3以上を使用していること
  • 対象のdbt projectにおいて、 metricsのdbt packageをversionを「1.3.0以上、1.4.0未満」でインストールしておくこと

参考記事

本記事で試すこと

Coalesce 2022の開催後dbtのコミュニティにて、Salesforce社でTableauのSolution EngineerをされているAlex Rossさんが、Tableauからdbt Semantic Layerに接続してMetricsを参照する、ということをデモされた動画を投稿していました。

これを実際に自分でもやってみて、ちょっと気になった所をプラスで検証したのが本記事で試した内容となります!

事前準備

以下の記事の内容に沿って、jaffle_shop_metricsのリポジトリをforkし、fork先の自身のリモートリポジトリのMainに対してコミット&マージしておきます。

※2023年1月29日時点、下記の記事でも触れていますが、/models/marts/average_order_amount.ymlにおいて、dimensionsの「has」を「had」に修正する必要があるためご注意ください。

検証した環境

参考までに、検証時に用いた各プロダクトやdbt packageのバージョンについて記しておきます。

  • dbt Cloud
    • dbt:1.3 ※Environmentsから指定
    • dbt-labs/metrics:1.3.2
    • dbt-labs/dbt_utils:1.0.0
  • Snowflake
    • 7.3.0
    • AWS、Asia Pacific(Tokyo)、Enterpriseエディション
  • Tableau
    • Tableau Desktop:2022.4.0

dbt Cloud上でSemantic Layerを構築

では、dbt Cloud上でSemantic Layerを構築していきたいと思います!

とは言っても行うことは非常に簡単で、Deployment Environmentを構築してジョブを一度実行したあと、対象のEnvironmentの設定を少し変更すればOKです。

Deployment Environmentの準備

まず、Environment Typeが「Deployment」の新しいEnvironmentを作成しておきます。

このときの注意点としては、dbt Versionを「Development Environmentと併せる」「1.3以上にする」、ということが必須となりますのでご注意ください。

Deployment Environmentでのジョブ設定・実行

Semantic Layerを有効化するには作成したDeployment Environmentで一度ジョブを実行する必要があるため、ジョブを設定して一度実行しておきます。

実行するコマンドはdbt buildだけでOKです。

Deployment Environmentの編集

続いてSemantic Layerは有効化するため、作成したEnvironmentを開きSettingsEditを押してください。

ここで、Semantic Layerという項目があるので、ここを「ON」にして、Saveします。

すると、Semantic Layerの項目の中にProxy Serverが新しく追加されます!このURLを用いてTableauから接続を行いますので、忘れずにメモしておきましょう。

Tableauからdbt Semantic Layerに接続

続けて、Tableauからdbt Semantic Layerに接続してみます!

Tableau Desktopを開き、接続先の一覧から「Snowflake」を選択します。

そして、以下の内容を入力し、「サインイン」を押します。

  • サーバー:dbt Cloud上で表示されたProxy ServerのURL
  • ユーザーパスワード:dbtのEnvironmentのDeployment Connectionで設定したSnowflakeアカウント上の任意のユーザー情報

これでTableauからdbt Semantic LayerのProxy Serverに接続完了です!通常のSnowflake接続と同じく、接続に使用したユーザーのロールに併せて使用できるウェアハウスやデータベースが選択出来るようになっています。

カスタムSQLを発行しdbtで定義したMetricsを参照する

続いてカスタムSQLを用いて、事前に定義済のMetricsをTableauから参照してみます。

シンプルにmetrics.calculateマクロを用いたクエリを発行する

まずは事前に定義済のMetricsを参照できるか確認するため、シンプルにmetrics.calculateマクロを用いたクエリを発行してみます。

すると、Metricsに沿った結果がデータとして得られました!

もちろんワークシートからの可視化も可能です!dbtのMetricsで事前に集計していることもあり、パパッとグラフが作れちゃいますね。

Tableauのパラメーターを用いて動的にtime_grainsとdimensionsを変更できるようにする

ただ、前述のやり方だと「他のdimensionsでも分析したいんだけど!」というときに都度新しいカスタムSQLを記述しないといけないため、正直面倒ですよね。

そこでTableauのパラメーターを用いて、動的にtime_grainsdimensionsを変更できるようにしてみます!

対象のカスタムSQLの画面上でパラメーターの挿入新しいパラメーターの作成を押します。

パラメーター作成のポップアップが出てきましたら、下図のようにリストの形式で、Metricsで事前に定義しておいたdimensionsを入力して、右下の「OK」を押します。

すると、カスタムSQL上にパラメーターが追加されます。

もう一つ、同じような流れでtime_grainsについてもパラメーターを作成しておきます。

この上で、SQLを書き換えます!色々と考慮する点があるため、注意が必要です。

  • 作成したパラメーターはJinjaのSet関数で変数化して使い回せるように
    • Proxy Serverを介してコンパイルされたSQLが実行される仕様なので、TableauのカスタムSQLでもJinjaが使えるのです
  • 使用するカラムを明示的にしておかないとエラーになるため、select句ではカラムを明示的に選択する
  • selectに関する注意事項1点目:date_{{time_grain}} as "日付"とすることで、metricsパッケージに含まれるdbt_metrics_default_calendar.sqlで生成されるカレンダーデータに対応
    • metricsパッケージで作成されるカレンダー周りの詳細は、公式Docをご確認ください
  • selectに関する注意事項2点目:cast({{dimensions_param}} as string) as "分析粒度"とすることで、dimensionの値が真偽値などであってもstringで扱うようにし、Tableauの型関係のエラーを防ぐ
  • selectに関する注意事項3点目:dbtで定義したMetricsのnameの値をselectすることで、集計値を表すカラムをselect出来る(ここでは、average_order_amountが該当)

これらのポイントを抑えた上で、書き換えたSQLが下記になります。

{% set time_grain=<パラメーター.time_grains> %}
{% set dimensions_param=<パラメーター.dimensions_list> %}

select
    date_{{time_grain}} as "日付",
    cast({{dimensions_param}} as string) as "分析粒度",
    average_order_amount
from {{ metrics.calculate(
    metric('average_order_amount'),
    grain=time_grain,
    dimensions=[dimensions_param]
) }}

このSQLをカスタムSQLとして設定した後、select句で選択した各カラムをワークシートで選択した上でパラメーターを変更していくと、動的にMetricsを介して取得するデータを変更できます!

カスタムSQL周りのカスタマイズは少し手間ですが、Tableau側から動的にmetrics.calculateの条件を変更して得られるデータの内容を変更できるのは嬉しいですよね!

事前にMetricsとして担保している指標のため、間違ったデータがTableau側で可視化される心配もありません。

最後に

Tableauからdbt Sematic Layerを介してMetricsを参照してみました。

Tableau側でのカスタマイズが少し必要ですが、dbtのMetricsで統制管理された指標をTableauの直感的な操作で条件を変更しつつ参照できるというのは非常に嬉しいのではないでしょうか。

実際、検証をやっていてすごく楽しかったですし、子供みたいな感想ですが「新時代」を感じましたw

dbtのMetricsとSemantic Layerはさらなる機能拡充が見込まれますので、今後も継続的にウォッチしていきます!