メインコンテンツへスキップ
見出し画像

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で補強するという二段構えが、現場でのベストプラクティスと言えるでしょう。

     
     
    ライトノベル、音楽制作、動画制作をやってます♪ デジマ、システム業界で15年以上、外資系のSaaS企業や日系の大手IT企業にてソリューションアーキテクトやプロジェクトマネージャーとして、多くの企業のIT導入やデータ基盤構築を支援してます。