🚀

dbt macro tips advent calendar 2022 day 14 - grantに関する便利なマクロ例

2022/12/14に公開

便利なデータ変換ツールである dbt の中のmacroに関するtipsを書いていく dbt macro tips Advent Calendar 2022 14日目です。

12日目はmetaに関しての話をしました。

今回はこのmetaを使った便利なpost-hookを作ります。

metaを使ったgrant post-hook

dbt 1.3.0 時代では grantsというconfigが提供されています。

https://docs.getdbt.com/reference/resource-configs/grants

今ではこちらを使えばよいのですが、やむおえず古いバージョンを使っていたり、このgrantsではできないような特殊な権限を与えたいというケースがあるとは思います。
そういう場合、post-hookでgrants構文のクエリを発行します。
今では使用頻度は少ないかもしれませんが、このgrants構文の発行に関してmetaを使った便利な方法を紹介しておきます。

まずはじめに、macroを呼び出している対象のmetaを取得することを試します。
こちらは、config経由で取得することが可能になっています。

configはCustom Materializationを作る方向けのドキュメントとして以下のようなものが用意されています。

https://docs.getdbt.com/reference/dbt-jinja-functions/config

12日目の内容をおさらいすると、metaの情報はconfigの一部として保存されていたので、この config.getを使用することで、metaの情報を取得できます。
試してみましょう。

macro/grants.sql
{%- macro grant_select_with_meta() %}
  {%- if execute %}
    {%- do log(config.get('meta'), info=True) %}
  {%- endif %}
{%- endmacro %}
models/text.sql
{{
    config(
        materialized='table',
        meta={
            'select_roles':[
                'pg_database_owner',
                'pg_read_all_data',
                'pg_monitor',
            ],
        },
        post_hook=[after_commit('{{ grant_select_with_meta() }}')],
    )
}}

SELECT 'text'
$ dbt build --select text
03:00:51  Running with dbt=1.3.1
03:00:51  Found 4 models, 4 tests, 0 snapshots, 0 analyses, 298 macros, 1 operation, 0 seed files, 0 sources, 0 exposures, 0 metrics
03:00:52  
03:00:52  Concurrency: 4 threads (target='dev')
03:00:52  
03:00:52  1 of 1 START sql table model dev.text .......................................... [RUN]
03:00:52  {'select_roles': ['pg_database_owner', 'pg_read_all_data', 'pg_monitor']}
03:00:52  1 of 1 OK created sql table model dev.text ..................................... [SELECT 1 in 0.17s]
03:00:52  
03:00:52  Running 1 on-run-end hook
03:00:52  ========== Begin Failure Tests  ==========
03:00:52  ========== End Failure Tests ==========
03:00:52  1 of 1 START hook: macro_tips_advcal.on-run-end.0 .............................. [RUN]
03:00:52  1 of 1 OK hook: macro_tips_advcal.on-run-end.0 ................................. [OK in 0.00s]
03:00:52  
03:00:52  
03:00:52  Finished running 1 table model, 1 hook in 0 hours 0 minutes and 0.48 seconds (0.48s).
03:00:52  
03:00:52  Completed successfully
03:00:52  
03:00:52  Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1

取得できていますね。

では、実際にgrant構文を発行するmacroを書いてみます。

macro/grants.sql
{%- macro grant_select_with_meta() %}
    {%- if execute %}
        {%- set meta = config.get('meta', {}) %}
        {%- if 'select_roles' in meta %}
            {%- for select_role in meta['select_roles'] %}
                {%- do log('grant select ' ~ this ~ ' to ' ~ select_role ~' role', info=True) %}
                GRANT SELECT ON TABLE {{ this }} TO {{ select_role }};
            {%- endfor %}
        {%- endif %}
    {%- endif %}
{%- endmacro %}
$ dbt build --select text
03:09:09  Running with dbt=1.3.1
03:09:09  Found 4 models, 4 tests, 0 snapshots, 0 analyses, 298 macros, 1 operation, 0 seed files, 0 sources, 0 exposures, 0 metrics
03:09:09  
03:09:10  Concurrency: 4 threads (target='dev')
03:09:10  
03:09:10  1 of 1 START sql table model dev.text .......................................... [RUN]
03:09:10  grant select "postgres"."dev"."text" to pg_database_owner role
03:09:10  grant select "postgres"."dev"."text" to pg_read_all_data role
03:09:10  grant select "postgres"."dev"."text" to pg_monitor role
03:09:10  1 of 1 OK created sql table model dev.text ..................................... [SELECT 1 in 0.21s]
03:09:10  
03:09:10  Running 1 on-run-end hook
03:09:10  ========== Begin Failure Tests  ==========
03:09:10  ========== End Failure Tests ==========
03:09:10  1 of 1 START hook: macro_tips_advcal.on-run-end.0 .............................. [RUN]
03:09:10  1 of 1 OK hook: macro_tips_advcal.on-run-end.0 ................................. [OK in 0.00s]
03:09:10  
03:09:10  
03:09:10  Finished running 1 table model, 1 hook in 0 hours 0 minutes and 0.47 seconds (0.47s).
03:09:10  
03:09:10  Completed successfully
03:09:10  
03:09:10  Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1

どうやら無事 grant構文が発行できたようですね。
このmacroはmetaが設定されてなければ何もしないので、全体の設定として一律にpost_hookに指定しておくと色々と楽になりますし、metaデータを充実させる動機にもなります。

皆様も是非metaを使ったmacroを作ってみてください。
metaデータを整備する動機づけの第1歩として、機能に関連付けてしまうのは手っ取り早い一歩となります。


15日目はmacro overrideの話をします。

Discussion