dbtを使い始めて数ヶ月が経った雑感

この記事は dbt Advent Calendar 2022 の25日目の記事です。dbtを使い始めて数ヶ月ほど経過したので、これまでの所感を書きます。

はじめに

dbt (data build tool) はデータ処理変換を担うフレームワークです[1]。データエンジニアリングにおいて重要なデータ分析の品質保証をデータモデルの構築、テスト、ドキュメンテーションをいった要素で実現します。とりわけDWHに統合して使われることが意図されており、ETLにおけるTransferの役割を実現してくれます。

Coalece2022の[3]のセッションでも語られていますが、この25年間、ストレージコストが低下したことや、よりデータへのアクセスが容易になったなったことで、足元ではすべての変換を一つのDWHで行うETLからELTへといった流れも出てきました。この流れによって、よりdbtが真価を発揮しやすい環境が整ってきたと言えると思います。

チームでデータ分析

個人的に感じているdbtの本質的な価値はデータ分析のプロセスの管理と効率化です。

特に現代データ分析においてはデータエンジニア一人で分析業務を担い切ることは少なく、チーム・組織として分析を高度化し、顧客により大きな価値を届けられるようなデータ分析プロセスの実現とその管理が求められます。

私が従事している業務でも、構造が同一のクエリを何度も何度も手書きし、それを都度レビューするといったプロセスに課題を感じてしました(何度同じクエリを書くのかといった開発者視点での課題であったり、ほぼ同じクエリだからという心理状態によるレビュー品質の低下といったレビュワー・チーム視点での課題など)。

SQLをチームで書いた経験のある方ならわかると思いますが、クエリのコードレビューには大きな集中力を要します。CTEに分解しながら手元で小さなダミーデータを用意したりしながら実行し、クエリ全体としても問題ないということを考えるレビューは大きな労力です。

弱い心を前に浅いレビューで通してしまったりすることもあり、それが積み重なると属人的なクエリのできあがりです。さらに大きなクエリは依存関係も複雑になりがちで、どの中間テーブルを使うのか、その中間テーブルの品質がどれくらい保証されているのかといった課題が発生しがち(「この中間テーブルって最新ですか?」とテーブル作成者にヒアリングして回ったり)で、結果として品質の低いデータ分析結果を顧客に届けることになりかねません。データやファクトに基づく意思決定を誤った方向に導き、ビジネス上の損失や信頼を毀損する結果にも繋がりえます。

ここまでの話を整理すると、以下3つに課題を感じていました。

  • 依存関係が複雑化し、認知的負荷が大きい
  • 中間テーブルの各カラムが満たすべき制約がわからず、設計が見えない
  • 同じようなクエリを都度レビューしなくてはいけない

dbtでの解決

依存関係が複雑化し、認知的負荷が大きい

この課題については、シンプルに dbt docs コマンドで可視化してくれることが、依存関係の把握を助けてくれます。Coalece2022の[4]のセッションではモデリングパターンを以下4つに分類し、これをリファクタリングするワークショップの様子が届けられていますが、可視化されるとどのパターンに分類されるのかがひと目で分かるので、改善へのステップがエスカレーターになっていることにもdbtというプロダクトの強さを感じます。

  • ソースから直接データをjoinしている
  • 同じデータセットから何度もjoinしている
  • 依存の依存をjoinしている
  • 成果物にソースを使っている

([4]の発表中より引用)

中間テーブルの各カラムが満たすべき制約がわからず、設計が見えない

テストが書けることで各カラムにどういった制約が見えるようになります。
uniquenot_nullaccepted_valuesrelationships (そのカラムが他テーブルに存在するreferential integrityの担保)といったテストが標準 [5]で用意されていますし、これら標準機能で手が届かないようなテストもdbt-utils [6]に解決策が用意されています(複数カラムを跨ったuniquenessを保証したいときに unique_combination_of_columns などをよく利用します)。これらも実態としてはJinjaマクロなので、さらに物足りないときは自作でき十分な柔軟性を備えていると思います。

そして[2] は、data profilingやdata contract、data pipelinesの文脈での話にはなりますが、データ品質問題に対するアプローチとして以下の流れを提案しています。

  1. 品質の低いデータを特定する(異常値など)
  2. 許容する値を規定する
  3. データパイプライン上で、顧客に届く前に、エラーを補足する

dbtのテストはこの2.と3.に対しての保証と見ることもできるでしょう。

個人的にはこれに加えてテストを見れば各カラムにどのような制約が掛かっているのか(どういう設計なのか)が理解しやすく、テスト自体がドキュメンテーションになる点も気に入っています。

同じようなクエリを都度レビューしなくてはいけない

dbtのデータ変換はSQLとJinjaを組み合わせて実現されています[7]。Jinja[8]はPython-likeなシンタックスを持つテンプレートエンジンです。dbtで利用できるマクロもJinjaを使って生成できるため、複雑なクエリを汎用化し、再利用性を得ることができます。これによって算術演算が多い等の低レベルのクエリや注意深いレビューが必要なクエリなどを一度十分なレビューをすることで品質を保ったまま再利用可能なクエリを生成することができます。

このJinjaマクロを使った方法で一定の解決をみているものの、マクロのメンテナンスコストも無視できないものだと感じています。モデリングによる解決とマクロでの解決の両軸をどのようにバランスさせていくかは個人的にも興味が向いている点です。「同じようなクエリを都度レビューしなくてはいけない」という課題で対象としているクエリを分解すると「ロジックが共通であるクエリ」と「低レベルのクエリ」があるように感じているので、前者はモデリング+マクロによる解決、後者はdbt Core v1.3で導入されたPython models [9] による解決が望ましいのではとも思え、このあたりは考えを深めていきたい論点になります(まだ視聴できていないのですが、Coalece2022でのなぜPython第二言語としたのかについてのセッション[10]で話されていたりしないかも気になっています)。

最後に

簡単ではありますが、dbtを使い始めて数ヶ月の雑感でした。まだまだ知らないことだらけではありますが、使い始める前に感じていた課題が解消されていてdbtの恩恵を感じています。何より複雑なSQLを書いていたときに比べて、構造化ができている点、しっかりと管理でき品質保証されている点に安心感を持って開発を進めることができています。dbt Advent Calendar 2022 を拝見していても、初めて知ることも多かったり、エコシステム自体が大きく成長しようとしている兆しも感じるところで、2023年もどのように変わっていくのか非常に楽しみな技術です。

References