[新機能]MetricFlow統合後のdbt Semantic LayerをTableau Desktopから参照してみた

2023.10.28

さがらです。

現地時間10月16日~10月19日で、dbt Coalesceが開催されました。

基調講演で発表された新機能については、下記のブログが参考になります。

この基調講演で、MetricFlow統合後のdbt Semantic Layerが一般提供になったと発表がありました!

連携できるパートナー製品も併せて発表され、なんとTableauも含まれています

ということで、実際にTableau DesktopからMetricFlow統合後のdbt Semantic Layerを参照してみたので、本記事でその内容をまとめてみます。

※Tableauからdbt Semantic Layerへ接続するコネクタは2023年10月28日時点ではBeta版のため、ご注意ください。

試す内容

下記の公式Docに沿って、Tableau Desktopからdbt Semantic Layerで定義されたmetricsを参照してみます。

dbt Semantic Layerの設定については、下記の公式Docを参考にします。

検証環境

  • dbt Cloud:Enterpriseエディション
  • 各Environmentのdbtバージョン:1.6
  • Tableau Desktop:2023.3
  • OS:Windows 10

事前準備

下記のリポジトリをforkしたdbt projectを事前にdbt Cloud上で定義し、Production Environmentを定義して、dbt seeddbt buildを含むジョブを実行しておきます。

下記の記事も参考になるはずです。

dbt Cloud上でのSemantic Layerの設定

まずdbt Cloud上の対象のdbt projectにおいて、Semantic Layerを有効化しておく必要があります。

Account settingsProjectsから対象のdbt projectを選択し、Configure Semantic Layerを押します。

続いて、このdbt projectで使用しているDWHへの認証情報を入力します。

最低でも、semantic_modelsmetricsが参照しているdbt Modelを含むスキーマ・テーブルへの読み取り権限が必要となります。

必要な情報を入力したら、右下のSaveを押します。

すると、Environment IDHostなどの情報が表示されます。

この上でTableau Desktopから接続するにはService Tokenが必要となりますので、Generate Service Tokenを押します。

任意のToken Nameを入れて、デフォルトのSemantic Layer OnlyMetadata Onlyが付与された状態で、右下のSaveを押します。

すると、Service Tokenが表示されます!この画面を離れると表示できなくなるので、忘れずにコピーしておきましょう。

Tableau Desktopからdbt Semantic Layerに接続

まず、https://github.com/dbt-labs/semantic-layer-tableau-connector/releases/download/v1.0.0/dbt_semantic_layer.tacoにアクセスして、コネクタをダウンロードし、下記の該当するフォルダに保存します。 ※もしコネクタのバージョンが古くなっている場合には、dbtの公式Docから最新のコネクタへのURLを確認してください。

  • Windows: C:\Users\\[Windows User]\Documents\My Tableau Repository\Connectors
  • Mac: /Users/[user]/Documents/My Tableau Repository/Connectors
  • Linux: /opt/tableau/connectors

次に、https://search.maven.org/remotecontent?filepath=org/apache/arrow/flight-sql-jdbc-driver/12.0.0/flight-sql-jdbc-driver-12.0.0.jarからJDBCドライバをダウンロードし、下記の該当するフォルダに保存します。 ※もしコネクタのバージョンが古くなっている場合には、dbtの公式Docから最新のコネクタへのURLを確認してください。

  • Windows: C:\Program Files\Tableau\Drivers
  • Mac: ~/Library/Tableau/Drivers
  • Linux: /opt/tableau/tableau_driver/jdbc

この状態でTableau Desktopを起動し、その他からdbt Labsによるdbt Semantic Layerを選択します。

すると、先程dbt Cloud上で確認したHostEnvironment IDService Tokenを入力する画面が出てきますので入力します。入力後、右下のサインインを押します。

これで、下図のような画面が出ればOKです!

実際にグラフを作ってみた

接続は無事に完了したので、早速グラフを作ってみたいと思います。

ワークシートに移動すると、MetricFlowで定義したsemantic_modelsdimensionsがディメンションとして、metricsがメジャーとして表示されているのがわかります。

特にディメンションにおいては、<entitiesのname>: <dimensionsのname>で表記されていることがわかります。

「type: simple」のmetricsでグラフ作成

早速グラフを作ってみます!

メジャーにmetricsで定義したtype: simpleOrder Total、ディメンションにdimensionsで定義したOrder Id: Ordered Atを選択します。

すると、下図のように無事にグラフを作れました!Order Id: Ordered Atは日付に関するディメンションですが、連続・非連続問わずグラフを作ることが可能です。

「type: derived」のmetricsでグラフ作成

次に、売上を計算するmetricsであるrevenueからコストを計算するmetricsであるorder_costを引いた、order_gross_profitというtype: derivedmetricsを可視化してみます。

※関連するmetricsの定義はこちらのコードになります。

metrics:
  - name: revenue
    description: Sum of the product revenue for each order item. Excludes tax.
    type: simple
    label: Revenue
    type_params:
      measure: revenue
  - name: order_cost
    description: Sum of cost for each order item.
    label: Order Cost
    type: simple
    type_params:
      measure: order_cost

~中略~

  - name: order_gross_profit
    description: Gross profit from each order.
    type: derived
    label: Order Gross Profit
    type_params:
      expr: revenue - cost
      metrics:
        - name: revenue
        - name: order_cost
          alias: cost

こちらも問題なく可視化できました!

もう一つtype: derivedの例として、売上を計算するmetricsであるrevenueを用いて、1ヶ月前のrevenueと比較したときの売上比率を計算するrevenue_growth_momを可視化してみます。

※関連するmetricsの定義はこちらのコードになります。

metrics:
  # Simple metrics
  - name: revenue
    description: Sum of the product revenue for each order item. Excludes tax.
    type: simple
    label: Revenue
    type_params:
      measure: revenue

  #Derived Metrics
  - name: revenue_growth_mom
    description: "Percentage growth of revenue compared to 1 month ago. Excluded tax"
    type: derived
    label: Revenue Growth % M/M
    type_params:
      expr: (current_revenue - revenue_prev_month)*100/revenue_prev_month
      metrics:
        - name: revenue
          alias: current_revenue
        - name: revenue
          offset_window: 1 month
          alias: revenue_prev_month

このような計算式が複雑なtype: derivedmetricsでも問題なく可視化できました!

「type: ratio」のmetricsでグラフ作成

次に、売上を計算するmetricsであるrevenueを分母に、foodに関連する売上のみを計算するmetricsであるfood_revenueを分子にした、割合を出すfood_revenue_pctというtype: ratiometricsを可視化してみます。

※関連するmetricsの定義はこちらのコードになります。

semantic_models:
  - name: order_item

~中略~

    measures:
      - name: revenue
        description: The revenue generated for each order item. Revenue is calculated as a sum of revenue associated with each product in an order.
        agg: sum
        expr: product_price
      - name: food_revenue
        description: The revenue generated for each order item. Revenue is calculated as a sum of revenue associated with each product in an order.
        agg: sum
        expr: case when is_food_item = 1 then product_price else 0 end

metrics:
  # Simple metrics
  - name: revenue
    description: Sum of the product revenue for each order item. Excludes tax.
    type: simple
    label: Revenue
    type_params:
      measure: revenue
  - name: food_revenue
    description: The revenue from food in each order
    label: Food Revenue
    type: simple
    type_params:
      measure: food_revenue

  #Ratio Metrics
  - name: food_revenue_pct
    description: The % of order revenue from food.
    label: Food Revenue %
    type: ratio
    type_params:
      numerator: food_revenue
      denominator: revenue

こちらも問題なく可視化できました!

2023年10月28日時点で注意すべきこと

「Tableau Desktopからdbt Semantic Layerが使える!!」ということで非常にテンションは上がるのですが、現状はいくつか注意すべき点があります。

semantic_modelsのentitiesでForeign Keyを定義しJOINできる関係である場合のみグラフを作れる

例えば、order_totalsemantic_models上でlocationcustomerに対するForeign Keyを定義しているため、Customer: <dimension名>Location: <dimension名>を一緒に選択してもエラーにはなりません。

実際のコードはこちらです。

semantic_models:
  - name: orders
    defaults:
      agg_time_dimension: ordered_at
    description: |
      Order fact table. This table is at the order grain with one row per order.
    model: ref('orders')
    entities:
      - name: order_id
        type: primary
      - name: location
        type: foreign
        expr: location_id
      - name: customer
        type: foreign
        expr: customer_id

~中略~

metrics:
  - name: order_total
    description: Sum of total order amonunt. Includes tax + revenue.
    type: simple
    label: Order Total
    type_params:
      measure: order_total

しかし、接続しているdbt projectでは他のsemantic_modelsも定義しており、例えばProduct: <dimension名>を選択すると下図のようにエラーが起きます。

このように、Tableau Desktop上で選択できるすべてのメジャーとディメンションの組み合わせでグラフを作れるわけではありません。これがdbt Semantic Layerを使うユーザー視点からすると少しわかりづらくなってしまうかもしれません。

現状は、MetricFlow上でsemantic_modelsentitiesでForeign Keyを定義しJOINできる関係である場合のみグラフを作れる、ということに注意が必要です。

measureでcount_distinctなどで定義していても、Tableau上のメジャーの表記はすべて「合計」となる

これはTableauに慣れている人ほど違和感があるかもしれませんが、semantic_modelsmeasurecount_distinctなどで定義している場合でも、Tableauのメジャーの表記上はすべて「合計」として表示されます。

例えば、下図はNew Customerという、Customer: Customer Typenewのユーザーのみに絞り込んでcustomer_id列でcount_distinctの集計を行うmetricsなのですが、Tableauのメジャー上は「合計」と表示されています。

かつ、これらのメジャーは「合計」以外に切り替えられないようになっています。

累計を出す「type: cumulative」のMetricsは上手く可視化できなそう

MetricFlowのmetricsでは、type: cumulativeで指定したmeasureの累計を出すことが可能なのですが、このtype: cumulativemetricsがTableau Desktop上では上手く可視化できないと感じました。

具体的には、type: cumulativemetricsであるCumulative Revenueと、ディメンションであるMetric Timeを併せてグラフを作ろうとしても下図のようにエラーとなってしまいました。

累積を出したい場合には、type: simpleでシンプルに売上を集計しているmetricsを選択し、Tableau Desktopの簡易表計算で「累計」を選択するのが良さそうです。

最後に

MetricFlow統合後のdbt Semantic LayerをTableau Desktopから参照してみました。

上述したような注意点はありますが、複数のmetricsを用いた計算を事前にdbt上で定義しておくことで、Tableau Desktop上で計算フィールドを駆使せずとも複雑な指標を可視化することができます!

2023年10月28日時点ではTableauからdbt Semantic Layerへの接続はBeta版なので、一部の注意点については今後の改善も見込まれると思います。

dbt × Tableauの組み合わせが更に進むと思う機能なので、今後にも期待したいです!