😽

dbtにおけるsqlfluff templater設定

2022/12/09に公開

はじめに

dbtのlinterとして皆さん使っているsqlfluffですが、templaterの設定を2パターン設定できるのはご存じでしょうか?小ネタとして消化して頂けますと幸いです。

dbt templater

pros/cons

  • pros
    • 特に設定をいじることなく簡単に導入できる
  • cons
    • dbt compileが必要になるため、重い

設定

sqlfluff-dbt-templaterをインストール

$ pip install sqlfluff-templater-dbt

.sqlfluff内でtemplater = dbtとdbt_project.yml, profiles.ymlへのパスを設定。

.sqlfluff
[sqlfluff]
templater = dbt

[sqlfluff:templater:dbt]
project_dir = <relative or absolute path to dbt_project directory>
profiles_dir = <relative or absolute path to the directory that contains the profiles.yml file>
profile = <dbt profile>
target = <dbt target>

簡単ですね。ただ何せ重いのでCIで用いるのは少し不向きかと思います。

jinja templater

pros/cons

  • pros
    • compileを行わずにレンダリングするため、比較的速い
  • cons
    • macroに対してダミーの返り値を用意する必要がある

設定

.sqlfluffの設定。macroの返り値や、ダミー値を返すlibraryのパスを設定する。

.sqlfluff
[sqlfluff]
templater = jinja

[sqlfluff:templater:jinja]
apply_dbt_builtins = True
load_macros_from_path = ./project/macros/
library_path = .sqlfluff_libs/

[sqlfluff:templater:jinja:macros]
# Macros provided as builtins for dbt projects
dbt_ref = {% macro ref(model_ref) %}{{model_ref}}{% endmacro %}
dbt_source = {% macro source(source_name, table) %}{{source_name}}_{{table}}{% endmacro %}
dbt_config = {% macro config() %}{% for k in kwargs %}{% endfor %}{% endmacro %}
dbt_var = {% macro var(variable, default='') %}item{% endmacro %}
dbt_is_incremental = {% macro is_incremental() %}True{% endmacro %}
run_query = {% macro run_query(query) %}True{% endmacro %}
# その他自作のmacroを追加

dbt_utilsなども別途.pyファイルで適当な返り値を用意する必要があります。

dbt_utils.py
def surrogate_key(list):
    return "mock"

def star(**kwargs):
    return "some_columns"

def union_relations(**kwargs):
    return """
    select
        test
    from
        test
    union all
    select
        test
    from
        test_2
    """

dbt_utils.starの引数は本来fromですが、pythonの場合fromは予約語で使えないので**kwargsで逃げています。実際のクエリとは異なるので、そこを考慮しておかないとたまにlintが落ちたりします。

私はこちらの設定を使用しています。

で、どっちがいいの?

個人的にはjinja templaterの方がdwhに接続せずにlintができるので好きです。ただpackageのmacroを追加するたびに.pyファイルでダミー値を用意しないといけないのでそこが少し手間かな、と思います。

その他

dbt cloudのformatterはsqlfmtを採用しているそうです。
複数行のselectでも改行せずに1行で書こうとするのが好みではないのでまだ採用していませんが、かなり高速で動作するので、もう少し柔軟にruleが設定できるようになればpre-commitなどで採用するのもよいかもしれません。

Discussion