dbt_project.ymlを使わずコマンドラインで変数を渡す方法
はじめに
こんにちは。
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_name
にDog
を指定した場合と指定しなかった場合の出力例です。
-- 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