
Databricks Declarative PipelineのExpectationsはPythonとSQLどちらで書くべきか?
DatabricksのDeclarative Pipelineでは、データ品質を担保するためのルール(Expectations)を宣言的に定義できます。ただ、実装方法として「SQL(YAMLに近い形式)」と「Python(DLTなどを活用)」の2つの選択肢があり、どちらを選ぶべきか迷う方も多いのではないでしょうか。本記事では、SQLとPythonのメリットや向いているケースを整理し、現場での使い分け方針を解説します。
SQLで書くメリット
ExpectationsをSQLライクな形式で書く最大のメリットは、シンプルで共有しやすいことです。
NULL禁止、数値範囲、文字列形式、重複チェックなどの定型ルールは、SQLで簡潔に表現可能
アナリストや非エンジニアでも読みやすく、レビューや監査のスピードが上がる
YAMLやSQL形式なら、ルールを一元的に管理でき、変更履歴の追跡もしやすい
Sparkネイティブで処理されるため、パフォーマンスも安定
つまり、**「定型ルールが中心」「ルールをチーム全体で共有したい」**といった場面ではSQLが最適です。
Pythonで書くメリット
一方で、Pythonを使うと柔軟な表現力を活かせます。
ウィンドウ関数を組み合わせた時系列チェックや履歴比較が可能
複数テーブルを横断した整合性検証、外部ライブラリによる高度なバリデーションも実現
pytestなどを利用すれば単体テストを回しやすく、CI/CDに組み込みやすい
UDFを定義して住所・氏名の正規化、異常検知モデルの呼び出しなど、複雑な処理を追加可能
つまり、**「単純なルールでは足りない」「外部ライブラリを使いたい」「テスト自動化を重視したい」**といった高度なユースケースではPythonが力を発揮します。
選び方のチェックリスト
迷ったときは次の観点で判断するとよいでしょう。
列単位の単純チェック中心 → SQL
外部ライブラリやUDFを使う必要がある → Python
業務担当者もルールを変更する可能性がある → SQL
履歴や複数テーブルを跨いだロジックが必要 → Python
監査やレビューを重視する → SQL
このように切り分けると、自ずと最適解が見えてきます。
実装例(サンプルコード)
Declarative Pipeline(YAML)
name: demo-orders-pipeline
catalog: main
schema: demo_dp
target: curated
sources:
orders_src:
table: source.orders_raw
sinks:
orders_clean_sink:
table: curated.orders_clean
mode: overwrite
orders_bad_sink:
table: quarantine.orders_bad
mode: append
transformations:
- name: clean_orders
read: orders_src
select:
- order_id
- customer_id
- amount
- email
expectations:
- name: not_null_customer
condition: "customer_id IS NOT NULL"
action: quarantine
- name: amount_range
condition: "amount >= 0 AND amount <= 1000000"
action: quarantine
- name: email_format
condition: "email RLIKE '^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$'"
action: quarantine
write:
pass: orders_clean_sink
fail: orders_bad_sink
DLT(Python)
import dlt
@dlt.table
@dlt.expect("not_null_customer", "customer_id IS NOT NULL")
@dlt.expect("amount_range", "amount >= 0 AND amount <= 1000000")
@dlt.expect("email_format", "email RLIKE '^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$'")
def clean_orders():
return spark.table("main.demo_dp.source.orders_raw").select(
"order_id", "customer_id", "amount", "email"
)SQL/YAMLではルールを宣言的に管理でき、Pythonでは柔軟に拡張できます。用途に応じて選択・併用するのが現実的です。
実務でのおすすめ運用スタイル
実際のプロジェクトでは「SQLで8割、Pythonで2割」という使い分けが最も現実的です。
SQL/YAML:必須チェック、範囲条件、形式チェックなど、日常的な品質ルールを網羅
Python:複雑な履歴依存チェック、外部辞書を使うバリデーション、機械学習による異常検知など限定的に活用
この二段構えにすることで、SQLの可読性とガバナンス、Pythonの柔軟性と拡張性の両方を享受できます。さらに、隔離データの扱いやメトリクス収集は共通ポリシーで揃えることで、運用がよりスムーズになります。
まとめ
Databricks Declarative PipelineのExpectationsは、SQLでもPythonでも記述できますが、それぞれ得意な領域があります。
SQLはシンプルで可読性が高く、標準ルールやガバナンスに最適
Pythonは柔軟性があり、複雑な処理や外部ライブラリ連携に強い
まとめると、まずはSQLで素早くルールを固め、必要に応じてPythonで補強するという二段構えが、現場でのベストプラクティスと言えるでしょう。