dbt Semantic LayerとStreamlitで硬く作るデータプロダクト

前置き

この記事はdbt Advent Calendar 2024の1日目の記事です。
この記事で提唱する内容は多くの論点をすっ飛ばしているものも多く、ツッコミどころもたくさんあると思いますが是非フィードバックを頂きながら議論を深めていければと思っています。

データを一定自由に使ってもらいたいけど無法地帯になりやすくて困っていませんか?

そんな悩みを持っているデータエンジニアやデータ管理者は多いと思います。
  • 「レポートで見ている売上と自分が計算したものが合致しないんだけど」
    • 勝手にクレンジングされていないデータを直接利用されてしまい、データの品質が保証できないデータが利用されてしまっていた
  • 「目的のデータを作れたと思うんだけど、どうもおかしい。知識もないから正しいデータの状態がわからないから見て欲しい」
    • モデル間の結合粒度の誤りや結合キーの不足でファンアウトしている
  • 「日次にあるこの集計軸を月次のレポートにもほしいんだけど」
    • 時系列の粒度ごとのメトリクスロジックと集計軸の管理が煩雑になってしまっている
      • 日次を最小粒度に、週次と月次をまとめているような構造になっている
      • 月次や週次に評価軸を足そうと思うと日次に追加して、更に改修する必要がある

データを正しく使ってもらう上で守りたいこと

  • 必要な検査や管理が出来ているデータを大前提利用してもらいましょう
  • 売上数や客数等の一見簡単そうな集計ロジックも独自に実装をせず、決められた方法で該当のデータを利用してもらいたい
  • 上記の品質の保証やデータの取得を継続的に提供ができる状態を作ること

dbt Semantic Layerとは?

dbt Semantic Layerは、dbt Labsが提供するデータ分析やデータ探索、データ活用のための新しい機能で、データモデルのロジックを一元的に管理し、複数のBIツールや分析ツールで一貫したデータ定義を共有するための仕組みです。似たような仕組みとしてはLookerのLookML、Cube等があります。
dbt Semantic Layerは「セマンティックモデル」と「メトリクス」を通じて、データを整理します。
  • SemanticModel: データの構造を明確化(データの粒度や次元を定義)。
  • Metrics: そのデータを基にしたビジネス指標を定義。
  • Dimensions: データを絞り込むための属性(例: 地域、日付)。
  • Measures: データ内での集計結果(例: 売上、在庫量)。
 
 
dbt Semantic Layerの内容理解を深めるためにはたぬさんがまとめてくれた以下の資料がとてもわかり易いので是非御覧ください。
 
実際にdbt Semantic LayerとSteep(BIツール)を利用しているkuwakenさんの記事も利用イメージとしてわかりやすいと思います。
 
dbt Semantic Layerの特徴的なところは以下だと思っています
  • 中核を構成するミドルウェアであるMetricflowはOSSでオープンである
    • dbt SemanticLayerはMetricflowを含んだAPIやキャッシュ機構の側を提供している
  • dbtの世界の中でデータモデルとそのメトリクスを統合的に管理できる
    • dbtのモデル開発やデータ品質、コントラクトの適用のアプローチの上にメトリクス管理を地続きで行いやすい
    • データリネージとしてモデルに関係するメトリクスも可視化が可能
  • dbt Cloudのチームプランは1ライセンス($100)から可能であり、現状では比較的安価にSemanticLayerを通じたデータ提供が可能
    • 現行の料金形態ではDeveloperライセンスを増やすのには費用がその分かかるが、SemanticLayer経由の使用ユーザー数等の制限はない
    • dbt Cloud自体はGithubレポジトリを中心とした開発が可能なため開発者全員がDeveloperライセンスを保有しなくても良い

データ利用者とのI/Fとなるdbt Semantic Layerとそれを活用したプロダクトをStreamlitで作る

ここまでの話で一定dbt Semantic Layerを通じて、dbtによるモデリングと周辺のテストやコントラクトによるデータ整備をベースにメトリクスロジックの定義集約できそうという感じは掴めたかと思います。
ここからは具体的にStreamlit(Python)からdbt Semantic Layerとやり取りをしてデータを取得する方法を説明します。
Streamlitから直接BigQueryを触ることはできますが、前述の通りガバナンスが効かなくなる可能性もあるため、以下のような構成で処理できるように解説をします。
 

dbt Semantic Layer APIを使うための設定

まずdbt CloudでSemanticLayerを使うEnviromentやジョブの設定、実行、また認証情報の登録や、APIトークンの発行をします。トークンは発行されたらメモをしておきましょう。

dbt-sl-sdkの登場

dbt Labs公式かdbt Semantic Layer SDK for PythonというSDKが提供されています。dbt Semantic Layer のAPIはJDBCやGraphQLといった通信方法で提供されていますが、その通信部分を考慮しなくて使えるようにラップしてくれています。
同期処理のタイプか非同期処理のタイプかを選べます。この記事では同期処理の方で解説をします。

通信処理の初期設定

SemanticLayerClientを呼び出し、SemanticLayerの設定をしたEnviromentIDと認証トークンを設定します。

定義されているメトリクスの一覧の取得

Semantic Modelで定義されているメトリクスをリストで取得が出来ます。

メトリクスデータの取得

queryを使います。
最低限はmetricsだけで動作ができ、必要に応じてgroup_byに必要なdimensionsを定義してください。
queryから返却されるデータはpyarrow形式なためそのままstreamlitの関数に渡せません。to_pandas()関数を呼び出すことでデータ形式を変換できるので変換して渡します。
 
polarsに渡したいときは以下のような事もできます。

metricsやdimensionsをGUIと連携させる

metricsに含まれるmetricオブジェクトはdimensionの情報も持っているため以下のような書き方をすればgroup byで指定したいdimsnsionを可視化・利用することが可能です。

まとめ

streamlitでの作り込み等もっと書けたらなと思ったのですがタイムオーバーでした。
 
実際にはdbt SemantiModelの実装方法はより複雑なメトリクスやデータ定義が可能です。
メトリクスに定義されている実際のディメンションの項目を抜き出しStreamlitのセレクターと紐づけたりすることでよりインタラクティブで使いやすい体験も生み出せそうなこともわかりました。
 
直近ではSCD-Type2を用いたモデリングへの考え方や実践例も提示され、去年の状態からの進捗を感じます。
 
またdbt Semantic Layerの資産は他のインテグレーションにもそのまま活用可能です。これからの広がりも楽しみですね(個人的にはevidenceやRillが対応してくれないかなと期待しています
 
権限周りの統制はより求められる気がしており、統合的なソリューションが生まれてくると良さそうだなと思っています。

勉強会をします!

本稿では書ききれない、探索しきれなかったことも多いので、Tokyo dbt Meetupの集まりでSemanticLayerの事に関する会を企画中です。是非ご参加ください!
このエントリーをはてなブックマークに追加