Snowflake×dbtを試してみた~Part2:Project設定編~ #SnowflakeDB #dbt

2021.12.20

※本エントリは、Snowflakeをより使いこなそう! Advent Calendar 2021の20日目の記事となります。

さがらです。

Snowflake公式のdbtと連携した時の機能を一通り試すことが出来るQUICKSTARTSに関して試してみた内容をまとめていきます。※この記事は「Part2:Project設定編」となります。

この記事の内容について

Snowflake公式のQUICKSTARTSに、Accelerating Data Teams with dbt & SnowflakeというSnowflakeとdbtを組み合わせたときの利点を一通り試すことが出来るクイックスタートがあります。

こちらの内容について、以下の合計5本の構成で試してみた内容を書いていきます。

この記事では、「Project設定編」ということで「6. dbt Project Configuration」の内容についてまとめていきます。

6. dbt Project Configuration

ここでは、記述するSQLなどを管理する最上位の概念であるProjectを設定して、サンプルModelを実行してどんな結果が得られるか、Projectの構成をどうやって変更するか、を見ていきます。

Projectの作成

左上のメニューバーのアイコンを押して頂いたあと、Developを押します。押した後はIDEの立ち上げのため、少し時間がかかるかと思います。

IDEが表示されたら、左上のInitialize your projectを押します。すると、新しいProjectが作られ、ファイルツリーに新しいファイルとフォルダが作成されているのが確認できるはずです。

Master Branchに一度Commitするため、左上のcommitを押した後に、任意の内容をCOMMIT MESSAGEに記述し、Commitを押してください。 (COMMIT MESSAGEは、Commit時点の状態を記録するものですので、どんな変更を施したかがわかるように記述することがおすすめです。これは、監査やデバッグを行う場合、加えて将来過去の開発内容を振り返るときにも役立ちます。組織上COMMIT MESSAGEに運用ルールがある場合にはその作法に従うようにしましょう。)

先程はMaster BranchにCommitをしましたが、実際に個別に開発を行うときには専用の作業領域、つまりはBranchを切る必要があります。次は実際に新しくBranchを切る作業を行ってみます。

左上のcreate new branch...を押して、BRANCH NAME欄にはdbt_snowflake_workshopと入力します。その上でSubmitを押します。

サンプルModelの実行

次に、dbtのスタータープロジェクトに付属するサンプルのModelを実行して、すべてが正しく初期化されたことを確認していきます。Modelに関して簡単に説明しておくと、SELECT文が記述されたもので、それぞれのModelが実行されることで記述されたSELECT文が実行され返ってきた結果を元に接続先のDWHにテーブルを構築します。

画面最下部のコマンドライン上でdbt runと入力し、Enterをクリックしてください。コマンドラインはdbtの各種コマンドを実行するために使用します。

それでは、実行後の結果を見ていきましょう。my_first_dbt_modelをクリックして展開してください。

Summaryでは、実行したmodelの処理時間などが記載されています。

Detailsでは、実行されたクエリと併せ、より詳細に実行された内容を確認することが出来ます。

続いて、実行されたModelによりSnowflake上でどんなテーブルとビューが構築されたかを確認してみます。

Snowflakeの画面に移動し、データベースPC_DBT_DB内のテーブルとビューを確認します。テーブルはMY_FIRST_DBT_MODEL、ビューはMY_SECOND_DBT_MODEL、が出来ていることがわかると思います。

Project構成の変更

続いて、dbt Projectの保守性を高めるために、新しくオブジェクトを作成したり、設定を変更していきます。

まずはdimensional modelingの構造に沿うように、フォルダを新しく追加していきます。

dbtのProject画面に戻り、modelsフォルダの横の「・・・」をクリックし、New Folderを押します。その後、「models/」に続けてstagingと入力して、Createを押します。

modelsフォルダの中にstagingが出来ていればOKです。

加えて、更に3つのフォルダを作成します。フォルダ作成の要領は上述の内容ですので、以下に実施する内容だけを記します。

  • stagingフォルダの横にある「・・・」をクリックして、knoemaという名前のフォルダを作ります。ここには、knoemaソースに特化したステージングモデルを入れていきます。
  • modelsの隣にある「・・・」をもう一度クリックします。今回は、ファイルパスをmodels/marts/coreと記入します。そうすると、modelsの下にmartsという新しいフォルダが作成され、その中にcoreというフォルダが作成されます。

この作業を実施後、下図のようなフォルダ構成となっていればOKです。

次に、dbt_project.ymlファイルを更新します。これは、dbtにリポジトリがdbtのプロジェクトであることを伝えるとともに、各種ファイル(modelなど)を保持するパスなどを明示的にするためのファイルです。

dbt_project.ymlというファイルをクリックします。まず、5行目でプロジェクト名をmy_new_projectから [任意の名前]_dbt_workshopに更新します。注意点としては、35行目の内容もこちらの内容に更新します。これにより、プロジェクトがよりパーソナライズされます。※私はsagara_dbt_workshopと命名しています。

続いて、dbt_project.ymlの34行目以降のmodelsパラメータの内容を更新します。

modelsパラメータでは、以下の内容を定義できます。

  • schema:各Modelがどのスキーマに対してテーブルなどのオブジェクトを生成するのか(対象のスキーマがない場合は自動で命名規則に基づきスキーマを作成します)
  • materialized:各Modelがテーブルやビューのうち、どの種別のオブジェクトを生成するのか

34行目以降の内容をまるごと下記の内容に置き換えてください。<任意の名前>_dbt_workshopについては先程設定したプロジェクト名を入れます。※※私の場合はsagara_dbt_workshopと命名していたので、その内容を入れています。

models:
  <任意の名前>_dbt_workshop:
      example:
          schema: example 
      staging:
          schema: staging
          materialized: view
      marts:
          schema: marts
          materialized: table

ここまでで、dbt_project.ymlの編集は完了です!編集完了後の内容を保存するため、右上のsaveを押します。

フォルダの追加とdbt_project.ymlへの編集を反映させるため、Commitしましょう。※Commit Messageは任意の内容でOKです。

スキーマ構築のためのマクロの定義

dbtがオブジェクトを構築するスキーマを定義するために使用するマクロを作っていきます。

まず、マクロはJinjaというPythonベースのテンプレート言語で書かれています。Jinjaを使うと、if文やforループなどの制御構造を作成したり、SQLのスニペットを抽象化してプロジェクト全体に適用できる再利用可能な関数にするなど、通常SQLでは不可能なことを行うことができます。

マクロを活用した事例などはこちらの記事も参考にしてみてください。

本題に戻りますが、dbt_project.ymlで各modelごとにschemaパラメータを定義していない場合、右上のProfile➟Credentials➟Partner Connect Trial➟Development CredentialsのSCHEMAがスキーマ名として設定されます。

※今回はSnowflakeのPartner Connectを用いてdbtのセットアップを行っているのでこの設定を入力する必要がなかったですが、自身で新しくProjectを作成するときにはこの設定が必要です。

これを別のスキーマ名に上書きするマクロ作成のため、macrosフォルダにgenerate_schema_name.sqlという名前のファイルを新規に作成します。

macrosフォルダの横の「・・・」を押して、macros/generate_schema_name.sqlと入力し、Creatteを押します。

generate_schema_name.sqlファイルが作成されたら、下記の内容をそのままコピーして貼り付けます。貼付け後は、右上のsaveも忘れずに押しましょう。

{% macro generate_schema_name(custom_schema_name, node) -%}

    {%- set default_schema = target.schema -%}
    {%- if custom_schema_name is none -%}

        {{ default_schema }}

    {%- else -%}

        {{ default_schema }}_{{ custom_schema_name | trim }}

    {%- endif -%}

{%- endmacro %}

この上で、もう一度コマンドラインでdbt runを実行してみましょう。すると、作成したマクロの内容に沿って、新しい名称でスキーマが定義されていることがわかると思います。デフォルトのスキーマ名の末尾にdbt_project.ymlschemaパラメータで定義した内容が追加されています。

ここで1点注意点として、実はgenerate_schema_name.sqlのマクロを自身で作成しなくても、dbt_project.ymlで各modelに対してschemaパラメータが定義されていれば、デフォルトのスキーマ名の末尾にdbt_project.ymlschemaパラメータで定義した内容が追加されるようになっています。

これは、custom schemaの命名ロジックは上述したJinjaのコードの内容で別途定義されているためです。これに対し、ユーザー側で別途作成したgenerate_schema_name.sqlで上書きすると、そのファイルで記述したロジックがcustom schemaの命名として適用されるようになっています。

このクイックスタートでgenerate_schema_name.sqlを新しく作成した理由は、スキーマの命名規則の説明と、このgenerate_schema_name.sqlをカスタマイズすることでユーザー独自の命名規則でスキーマを定義することが出来る事を説明したかったことが狙いです。

このスキーマに関する仕様は下記の記事でも説明されていますので、併せてご覧ください。

Snowflakeの履歴にクエリタグを付けるマクロの定義

続いて、別のマクロを定義していきます。マクロの内容としては、Snowflakeの履歴にあるすべてのdbtの実行に対してクエリタグを追加する、というものです。

まず、新しいマクロのファイルを定義します。

macrosフォルダに対して、query_tag.sqlというファイルを新しく作成します。

作成後、下記の内容をコピーして貼り付けし、右上のsaveを押します。

{% macro set_query_tag() -%}
  {% set new_query_tag = model.name %} {# always use model name #}
  {% if new_query_tag %}
    {% set original_query_tag = get_current_query_tag() %}
    {{ log("Setting query_tag to '" ~ new_query_tag ~ "'. Will reset to '" ~ original_query_tag ~ "' after materialization.") }}
    {% do run_query("alter session set query_tag = '{}'".format(new_query_tag)) %}
    {{ return(original_query_tag)}}
  {% endif %}
  {{ return(none)}}
{% endmacro %}

マクロの定義が出来ましたので、再度コマンドラインでdbt runと入力し実行します。

実行後にSnowflakeの画面から履歴を確認してみます。一番右のクエリタグ列に、dbtを介して実行されたmodel名が記載されているのがわかると思います。これが、先ほど新しく定義したquery_tag.sqlの効力です。

PC_DBT_USERでフィルタをかけると尚わかりやすいと思います。

Packageのインストール

次章以降で使用する、Packageをインストールしておきます。

dbtパッケージとは、基本的に自分のdbtプロジェクトにインストールして、インストールしたコードにアクセスし、自分のものとして使うことができるdbtプロジェクトのことです。※プログラミングでいうライブラリに近いものです。

このクイックスタートでは、dbt_utilsパッケージの便利なマクロを使用して、複雑なSQLを書く方法を次章以降で紹介予定です。

dbt_utilsについては下記の記事でも検証しておりますので、こちらも併せてご覧ください。

では、さっそくdbt_utilsパッケージをインストールしていきましょう!packages.ymlというファイルを、dbt_project.ymlファイルと同じ階層に作成します。

その上で、作成されたpackages.ymlに対して以下の内容をコピーして貼り付けし、右上のsaveを押します。

packages:
  - package: dbt-labs/dbt_utils
    version: 0.8.0

ここまで出来たら、コマンドラインでdbt depsを実行してパッケージのインストールを行います。

下図のように表示されたら、パッケージのインストールは完了です!

ここで1つ注意点として、versionについては使用しているdbtのversionによっては適切にインストールできない可能性があるため、必要に応じてpackages.ymlversionの値を変更する必要があります。

実際私もdbtのversionが1.0.0だったのですが、これでは公式のテキストに記載されていたdbt_utilsのversion0.7.1がインストールできませんでした。

最新のdbt_utilsのversionはこちらのDocから確認できますので、必要に応じてご確認ください。

ここまで出来たら、Commitしましょう。Commitし終えたら、"6. dbt Project Configuration"は終わりです。

次回

Snowflakeをより使いこなそう! Advent Calendar 2021、次回の21日目では、「Snowflake×dbtを試してみた~Part3:パイプライン構築編その1~」というタイトルで執筆します。お楽しみに!