4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

dbt-osmosisの挙動を調べてみた 〜①標準機能編〜

Last updated at Posted at 2024-07-14

最近 dbt-osmosis を触って挙動などを調べてみたのでその結果を記事にまとめてみます。

この記事では dbt-osmosis の導入方法や標準機能の挙動についてまとめています。

dbt-osmosis とは?

公式リポジトリ:

dbt-osmosis は YAML ファイル(ソース YAML ファイル、スキーマ YAML ファイル)を自動生成してくれたり、上流テーブルのカラムの description などを下流へ伝搬してくれたりするツールです。

dbt-osmosis の有用性は次のスライドのp19~21が分かりやすいです。

導入

STEP 1|インストール

pip install dbt-osmosis

公式ドキュメント: Installation | dbt-osmosis Docs

STEP 2|dbt_project.yml にスキーマ YAML ファイルの生成先を指定する

指定方法:

models:
  <your_project_name>:
    +dbt-osmosis: <path>   # models/ からの相対パスとして扱われます

指定方法いろいろ:

models:
  your_project_name:
    # プロジェクト全体に適用される設定
    +dbt-osmosis: "_{model}.yml" # {model} はモデル名を参照できるコンテキスト変数

    staging:
      # サブフォルダを指定することも可能(この場合、 models/schema/ ディレクトリ内にスキーマ YAML ファイルが生成される)
      +dbt-osmosis: "schema/{model}.yml"

    intermediate:
      # Materialization に基づいてファイルを分けることも可能
      +dbt-osmosis: "{node.config[materialized]}/{model}.yml" # {node} はノード情報を参照できるコンテキスト変数。ノード情報は manifest.json で確認できる

    marts:
      # 固定ファイルを指定することも可能
      +dbt-osmosis: "prod.yml"    

    utilities:
      # 親フォルダの名前を指定することも可能
      +dbt-osmosis: "{parent}.yml" # {parent} は親フォルダ名を参照できるコンテキスト変数

公式ドキュメント:

標準機能

dbt-osmosis の標準機能を試してみた結果を下記に示します。

実行環境は次のとおりです:

requirements.txt
dbt-bigquery==1.6
dbt-osmosis==0.12.9

Document

機能

  • YAML ファイルのカラムの順番を変更してデータベースのカラムの順番に合わせる
  • データベースに存在するカラムを YAML ファイルに追加する
  • データベースに存在しないカラムを YAML ファイルから削除する
  • カラムレベルのドキュメントを上流モデルから下流モデルに受け渡す (下流モデルにそのカラムのドキュメントがない場合)

公式ドキュメント を DeepL で翻訳したもの

dbt-osmosis yaml document [--project-dir] [--profiles-dir] [--target]

実際に試してみた

前準備

:one: 各種ファイルを配置

次のディレクトリ構造で各種ファイルを配置します。

ディレクトリ構造
.
|-- dbt_project.yml
|-- models/
    |-- _source.yml
    |-- customers.sql
    |-- stg_customers.ql
    |-- stg_orders.sql

dbt_project.yml の models: の箇所を次のようにします。

dbt_project.yml(models:の部分のみ抜粋)
models:
  my_dbt_project:
    +materialized: table
    +dbt-osmosis: "_schema.yml"

_source.yml の中身を次のようにします。

_source.yml
version: 2

sources:
  - name: YOUR_GC_DATASET
    database: YOUR_GC_PROJECT_ID
    tables:
      - name: raw_customers
      - name: raw_orders

配置済みのサンプルコードは次のリポジトリにあります。

今回、 dbt モデルは次のような構造で用意しました。

:two: dbt run を実行

Q. なぜ dbt run を実行するのか?

dbt-osmosis は処理の中でデータベース上に実体化された dbt モデルの情報を参照します。そのため、一度データベース上に dbt モデルを実体化しておく必要があります。

試行1|そのまま実行

前準備のまま、何も手を加えず実行してみます。

実行コマンド:

dbt-osmosis yaml document

実行結果:

  • _source.yml にカラム情報が追加されている
  • _schema.yml は生成されていない
:pencil: 実際の _source.yml と _schema.yml
_source.yml
version: 2

sources:
  - name: <YOUR_DATASET>
    database: <YOUR_DATABASE>
    tables:
      - name: raw_customers
        columns:
          - name: id
            description: ''
            data_type: INT64
          - name: first_name
            description: ''
            data_type: STRING
          - name: last_name
            description: ''
            data_type: STRING
      - name: raw_orders
        columns:
          - name: id
            description: ''
            data_type: INT64
          - name: user_id
            description: ''
            data_type: INT64
          - name: order_date
            description: ''
            data_type: DATE
          - name: status
            description: ''
            data_type: STRING
_schema.yml
(存在しない)

試行2|_schema.ymlを用意して実行

次のような models/_schema.yml を用意して実行してみます。

_schema.yml
version: 2

models:
  - name: customers

実行コマンド:

dbt-osmosis yaml document

実行結果:

  • _schema.yml が作成され、 customers モデルのカラム情報が記載されている

Document 機能では、最低限スキーマ YAML ファイルを作成し、 - name: モデル名 まで書いてあげる必要があるようです。

:pencil: 実際の _schema.yml
_schema.yml
version: 2

models:
  - name: customers
    columns:
      - name: customer_id
        description: ''
        data_type: INT64
      - name: first_name
        description: ''
        data_type: STRING
      - name: last_name
        description: ''
        data_type: STRING
      - name: first_order_date
        description: ''
        data_type: DATE
      - name: most_recent_order_date
        description: ''
        data_type: DATE
      - name: number_of_orders
        description: ''
        data_type: INT64

試行3|_schema.ymlに不要なカラムを追加してみる

試行2の後、 _schema.yml に次の不要なカラムの情報を追記してコマンドを実行してみます。

_schma.yml
    version: 2
    
    models:
      - name: customers
        columns:
          - name: customer_id
            description: ""
            data_type: INT64

〜〜(略)〜〜

          - name: number_of_orders
            description: ""
            data_type: INT64
+         - name: hoge # 追加

実行コマンド:

dbt-osmosis yaml document

実行結果:

  • 追加した - name: hoge が消えている

Document 機能の説明通り、データベースに存在しないカラムが YAML ファイルから削除されています。

:pencil: 実際の _schema.yml
_schema.yml
version: 2

models:
  - name: customers
    columns:
      - name: customer_id
        description: ""
        data_type: INT64
      - name: first_name
        description: ""
        data_type: STRING
      - name: last_name
        description: ""
        data_type: STRING
      - name: first_order_date
        description: ""
        data_type: DATE
      - name: most_recent_order_date
        description: ""
        data_type: DATE
      - name: number_of_orders
        description: ""
        data_type: INT64

参考

Organize

機能

  • dbt_project.yml ファイルの dbt-osmosis var に基づいて、ソースが存在しない場合はブートストラップします。
  • dbt_project.ymlファイルに設定されたdbt-osmosis config(理想的には)に基づいて、YAMLファイルを移行します。
  • プロジェクトが宣言的な仕様にマッチしていることを確認します(つまり、YAMLファイルが正しい場所にあり、正しい名前を持っている)。

公式ドキュメント を DeepL で翻訳したもの

dbt-osmosis yaml organize [--project-dir] [--profiles-dir] [--target]

実際に試してみた

前準備

:one: 各種ファイルを配置

※ Document 機能を試した時と同じです。

配置済みのサンプルコード:

:two: dbt run を実行

試行1|そのまま実行

前準備のまま、何も手を加えず実行してみます。

実行コマンド:

dbt-osmosis yaml organize

実行結果:

  • _schema.yml が作成され、カラム情報が書き込まれている
:pencil: 実際の _source.yml と _schema.yml
_source.yml
(変化なし)
_schema.yml
version: 2
models:
  - name: stg_customers
    columns:
      - name: customer_id
        description: ''
      - name: first_name
        description: ''
      - name: last_name
        description: ''
  - name: customers
    columns:
      - name: customer_id
        description: ''
      - name: first_name
        description: ''
      - name: last_name
        description: ''
      - name: first_order_date
        description: ''
      - name: most_recent_order_date
        description: ''
      - name: number_of_orders
        description: ''
  - name: stg_orders
    columns:
      - name: order_id
        description: ''
      - name: customer_id
        description: ''
      - name: order_date
        description: ''
      - name: status
        description: ''

参考

Refactor

機能

  • dbt_project.yml ファイルの dbt-osmosis var に基づいて、ソースが存在しない場合はブートストラップします。
  • dbt_project.ymlファイルに設定されたdbt-osmosis config(理想的には)に基づいて、YAMLファイルを移行します。
  • プロジェクトが宣言的な仕様にマッチしていることを確認します(つまり、YAMLファイルが正しい場所にあり、正しい名前を持っている)。
  • YAMLファイルのカラムの並び順をデータベースのカラムの並び順と一致させます。
  • データベースに存在するカラムを YAML ファイルに追加する。
  • データベースに存在しないカラムをYAMLファイルから削除する
  • 上流モデルから下流モデルにカラムレベルのドキュメントを受け渡す (下流モデルにそのカラムのドキュメントがない場合)

このコマンドは、documentコマンドとorganizeコマンドを正しい順序で実行したものである。

公式ドキュメント を DeepL で翻訳したもの

dbt-osmosis yaml refactor [--project-dir] [--profiles-dir] [--target]

実際に試してみた

前準備

:one: 各種ファイルを配置

※ Document 機能を試した時と同じです。

配置済みのサンプルコード:

:two: dbt run を実行

試行1|そのまま実行

前準備のまま、何も手を加えず実行してみます。

実行コマンド:

dbt-osmosis yaml refactor

実行結果:

  • _source.yml にカラム情報が追加されている
  • _schema.yml が自動で作られ、すべてのテーブルについてカラム情報が追加されている
:pencil: 実際の _soruce.yml と _schema.yml
_source.yml
version: 2

sources:
  - name: YOUR_GC_DATASET
    database: YOUR_GC_PROJECT_ID
    tables:
      - name: raw_customers
        columns:
          - name: id
            description: ''
            data_type: INT64
          - name: first_name
            description: ''
            data_type: STRING
          - name: last_name
            description: ''
            data_type: STRING
      - name: raw_orders
        columns:
          - name: id
            description: ''
            data_type: INT64
          - name: user_id
            description: ''
            data_type: INT64
          - name: order_date
            description: ''
            data_type: DATE
          - name: status
            description: ''
            data_type: STRING
_schema.yml
version: 2
models:
  - name: stg_customers
    columns:
      - name: customer_id
        description: ''
        data_type: INT64
      - name: first_name
        description: ''
        data_type: STRING
      - name: last_name
        description: ''
        data_type: STRING
  - name: stg_orders
    columns:
      - name: order_id
        description: ''
        data_type: INT64
      - name: customer_id
        description: ''
        data_type: INT64
      - name: order_date
        description: ''
        data_type: DATE
      - name: status
        description: ''
        data_type: STRING
  - name: customers
    columns:
      - name: customer_id
        description: ''
        data_type: INT64
      - name: first_name
        description: ''
        data_type: STRING
      - name: last_name
        description: ''
        data_type: STRING
      - name: first_order_date
        description: ''
        data_type: DATE
      - name: most_recent_order_date
        description: ''
        data_type: DATE
      - name: number_of_orders
        description: ''
        data_type: INT64

試行2|カラム情報を伝搬させてみる

_schema.yml に次の変更を加えて実行してみます。

_schema.yml
〜〜(略)〜〜

      - name: stg_customers
        columns:
          - name: customer_id
-           description: ''
+           description: 'hogehoge' # 編集
            data_type: INT64

〜〜(略)〜〜

実行コマンド:

dbt-osmosis yaml refactor

実行結果:

  • customers モデルの customer_id カラム の description が hogehoge となっている
    • →伝搬してることがわかる
:pencil: 実際の _schema.yml
_schema.yml
version: 2
models:
  - name: stg_customers
    columns:
      - name: customer_id
        description: "hogehoge" # 編集
        data_type: INT64
      - name: first_name
        description: ""
        data_type: STRING
      - name: last_name
        description: ""
        data_type: STRING
  - name: stg_orders
    columns:
      - name: order_id
        description: ""
        data_type: INT64
      - name: customer_id
        description: ""
        data_type: INT64
      - name: order_date
        description: ""
        data_type: DATE
      - name: status
        description: ""
        data_type: STRING
  - name: customers
    columns:
      - name: customer_id
        description: "hogehoge"
        data_type: INT64
      - name: first_name
        description: ""
        data_type: STRING
      - name: last_name
        description: ""
        data_type: STRING
      - name: first_order_date
        description: ""
        data_type: DATE
      - name: most_recent_order_date
        description: ""
        data_type: DATE
      - name: number_of_orders
        description: ""
        data_type: INT64

結び

この記事では dbt-osmosis の標準機能について、実際の挙動をまとめました。記事に誤りなどありましたらご指摘いただけますと幸いです :bow:

標準機能の中で最もよく使うのは Refactor かと思います。次の記事で Refactor のコマンドオプションについてもまとめていますので、よろしければご覧ください。

ここまでお読みいただきありがとうございました :bow:

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?