💽

dbt_project.ymlを使わずコマンドラインで変数を渡す方法

2024/12/10に公開

はじめに

こんにちは。
2024年4月より広告営業から職制転換し、主にSQLやPythonを使ってデータ処理を行っているデータエンジニアの竹内です。
本記事では、dbtプロジェクトにおいてコマンドラインから変数を受け渡す方法について、具体的な例を用いて解説します。

今回実現したいこと

  • コマンドラインで変数を渡すことでdbtのクエリを変えたい

この方法を使うことでdbt_project.ymlを汚さずに、環境の切り替えやユーザー毎のカスタマイズ、テストデータの切り替えといったユースケースに対応することが可能です。

サンプルテーブルの作成(本記事ではSnowflakeを使用)

Snowflake上にサンプルテーブルを作成し、
動物の名前とその鳴き声を含むデータを格納します。

-- アニマルテーブルの作成
CREATE OR REPLACE TABLE animals_data (
    id INT,
    name STRING,
    call STRING
);

-- データの挿入
INSERT INTO animals_data (id, name, call) VALUES
(1, 'Dog', 'Bark'),
(2, 'Cat', 'Meow'),
(3, 'Horse', 'Neigh'),
(4, 'Cow', 'Moo'),
(5, 'Sheep', 'Baa');

モデル定義YAMLファイルの作成

dbtプロジェクトのモデル定義ファイルを作成します。

version: 2
models:
  - name: animal
    columns:
      - name: id
      - name: name
      - name: call

sources:
  - name: animals
    database: xxxxxxxx  # 使用するデータベース名を記載
    schema: xxxxxxxx  # 使用するスキーマ名を記載
    tables:
      - name: animals_data

animalsというソースを定義し、その中にanimals_dataというテーブルを指定しています。
また、animalというモデルを定義し、そのカラムをリストアップしています。

モデルSQLの作成

dbtモデルディレクトリにSQLファイルを作成し、
特定の動物名に基づいてデータをフィルタリングするクエリを記述します。

SELECT
    *
FROM
    {{ source('animals', 'animals_data') }}
    -- モデル定義ymlのsourcesを使用
WHERE
    name = '{{ var('animal_name', 'Cat') }}'
    -- コマンドラインで受け取った変数を出力する

source関数を使用してanimals_dataテーブルを参照し、
var関数を使用してコマンドラインから渡された変数animal_nameを使用しています。
変数が渡されない場合はデフォルトでCatが使用されます。

コマンドラインからの変数受け渡し

dbtコマンドを実行する際に、--varsオプションを使用して動物名を渡します。
以下のコマンドを使用して、animal_name変数にDogを渡します。

dbt build --select animal --vars '{"animal_name": "Dog"}' # json記法
もしくは
dbt build --select animal --vars 'animal_name: Dog' # yml記法

これにより、dbtはanimal_name変数をDogとして認識し、クエリ内で使用します。

解説

以下のコードは、変数animal_nameが存在する場合はその値を出力し、存在しない場合はデフォルト値のCatを出力します。

name = {{ var('animal_name', 'Cat') }}

-- Dogを渡した場合: name = Dog
-- 変数を渡さない場合: name = Cat

ただし、このままではSQLをコンパイルした際にname = Catとなり、識別子として扱われてしまいます。
これを防ぐために、シングルクォーテーションで囲んで文字列として扱います。

name = '{{ var('animal_name', 'Cat') }}'

-- Dogを渡した場合: name = 'Dog'
-- 変数を渡さない場合: name = 'Cat'

これにより、SQLクエリが正しくコンパイルされ、文字列として比較されます。

おまけ: 実際に出力されるSQL

dbtが生成するSQLは、targetディレクトリから確認できます。以下は、animal_nameDogを指定した場合と指定しなかった場合の出力例です。

-- Dogを指定した場合
create or replace view xxxxxx.xxxxxx.animal as (
    SELECT
    *
FROM
    xxxxxx.xxxxxx.animals_data
WHERE
    name = 'Dog'
);

-- 指定しなかった場合
create or replace view xxxxxx.xxxxxx.animal as (
    SELECT
    *
FROM
    xxxxxx.xxxxxx.animals_data
WHERE
    name = 'Cat'
);

コンパイルされたSQLを確認することで、dbtが生成するSQLクエリがどのように変数を使用しているかを確認できます。

まとめ

本記事では、dbtプロジェクトにおいてコマンドラインから変数を受け渡す方法について解説しました。

今後もデータエンジニアリングに関する有益な情報を提供していきますので、ぜひ他の記事もご覧いただけると幸いです。
また、質問やフィードバックがありましたら、コメント欄にてお気軽にお知らせください。

Discussion