Slide 1

Slide 1 text

{{ config(materialized=’incremental’) }} dbt Tokyo Meetup #3 5月10日(火曜日)11時〜12時            インクリメンタル https://developers.freee.co.jp/entry/understand-of-perfect-understandingより引用 『完全に理解した』、 〜そして、『何もわからない』へ〜 通称:ダニング ⹀クルーガー曲線 面白法人 カヤック 池田将士 ※ちなみに正式名称は株式会社です

Slide 2

Slide 2 text

自己紹介 池田 将士 (@mashiike) 技術部 SREチーム所属 職能、肩書きetc… ● (自称)データエンジニア ● (仮称)アナリティクスエンジニア ● SRE ● サーバーサイドエンジニア Amazon S3 ※私のIconはS3バケットではありません

Slide 3

Slide 3 text

会社紹介 鎌倉の地にて、主にWeb技術を用いて 人の印象に深く残るような面白コンテンツを作る会社 ゲームからWebサービス、ミュージアムetc… 様々なことに挑戦

Slide 4

Slide 4 text

事業紹介 DBT + Data Vault 2.0 on Amazon Redshift 大会プラットフォームサービス『Tonamel』 Tonamelのデータ基盤にて

Slide 5

Slide 5 text

アジェンダ 1. DBTとMaterialization 2. {{ config(materialized=’incremental’) }} 『完全に理解した』 a. 基本的な使い方 b. ログ処理での例 3. {{ config(materialized=’incremental’) }}『なにもわからない』 a. カラムに変更が入ったら? b. 再処理したくなったら? c. upsertを実現するには? 4. incremental、それは... 今日のゴール

Slide 6

Slide 6 text

DBTとMaterialization DBTには4つのMaterializationが標準搭載されています( Custom materializationを作ることも可能)

Slide 7

Slide 7 text

DBTとMaterialization DBTには4つのMaterializationが標準搭載されています( Custom materializationを作ることも可能) ● table:  SELECTの結果を物理テーブル として保存する ● view:  SELECTの結果を物理ビューと して保存する

Slide 8

Slide 8 text

DBTとMaterialization DBTには4つのMaterializationが標準搭載されています( Custom materializationを作ることも可能) ● table:  SELECTの結果を物理テーブル として保存する ● view:  SELECTの結果を物理ビューと して保存する ● ephemeral:  共通テーブル式(CTE)と して、他のモデルの実行時に埋め込ま れる

Slide 9

Slide 9 text

DBTとMaterialization DBTには4つのMaterializationが標準搭載されています( Custom materializationを作ることも可能) ● table:  SELECTの結果をDBテーブルと して保存する ● view:  SELECTの結果をDBビューと して保存する ● incremental: なんかいい感じに 物理テーブルを更新してくれるやつ!!(雑) ● ephemeral:  共通テーブル式(CTE)と して、他のモデルの実行時に埋め込ま れる

Slide 10

Slide 10 text

Q. 『いい感じに』って具体的にどういう事?

Slide 11

Slide 11 text

Q. 『いい感じに』って具体的にどういう事? 初回実行時

Slide 12

Slide 12 text

Q. 『いい感じに』って具体的にどういう事? 初回実行時 2回目以降

Slide 13

Slide 13 text

Q. 『いい感じに』って具体的にどういう事? 初回実行時 2回目以降 なんか! いい感じに!! Tableを更新してる!!!!

Slide 14

Slide 14 text

つまり・・・ ● 初回実行時は赤枠の中を描画しない で CREATE TABLE ● 2回目以降は赤枠の中を描画して INSERT TABLE

Slide 15

Slide 15 text

つまり・・・ ● 初回実行時は赤枠の中を描画しない で CREATE TABLE ● 2回目以降は赤枠の中を描画して INSERT TABLE {{ config(materialized=’incremental’) }} とは 1つのモデルを、1つの物理テーブルとして実現し       継続的に更新し続けるものなり!

Slide 16

Slide 16 text

実例:ログの処理の例 schema.yml version: 2 sources: - name: log tables: - name: nginx_access_logs description: nginxのアクセスログ columns: - name: time description: アクセス時刻 - name: method description: リクエストメソッド - name: uri description: リクエストされた URI - name: protocol description: リクエストのプロトコル - name: status description: レスポンスステータスコード - name: vhost description: リクエストされたホスト名 - name: request_id description: リクエストID - name: partition_date description: ログ読み出しのパーティション ● 初回実行時は全行ロード ● 2回目以降は直近7日の未ロードのみ ※Redshift Spectrumを用いて読んでいて、 重複がなく、request_idで識別できることを想定した例です。

Slide 17

Slide 17 text

{{ config(materialized=’incremental’) }} 完全に理解した!!! 通称:ダニング ⹀クルーガー曲線 きっと今この辺

Slide 18

Slide 18 text

{{ config(materialized=’incremental’) }} とは 1つのモデルを、1つの物理テーブルとして実現し 継続的に更新し続けるもの  

Slide 19

Slide 19 text

{{ config(materialized=’incremental’) }} とは 1つのモデルを、1つの物理テーブルとして実現し 継続的に更新し続けるもの   つまり、運用が発生する

Slide 20

Slide 20 text

{{ config(materialized=’incremental’) }} とは 1つのモデルを、1つの物理テーブルとして実現し 継続的に更新し続けるもの   つまり、運用が発生する a. 途中でカラムが増えてたら・・・ b. 再処理したくなったら・・・ c. upsertを実現するには・・・ etc. 例えば、運用中にこんな事思ったりしません?

Slide 21

Slide 21 text

ようこそ! 通称:ダニング ⹀クルーガー曲線 きっと今この辺 『何もわからない』への扉へ {{ config(materialized=’incremental’) }}

Slide 22

Slide 22 text

ようこそ! 通称:ダニング ⹀クルーガー曲線 きっと今この辺 『何もわからない』への扉へ {{ config(materialized=’incremental’) }} incrementalの難しさは運用にあり

Slide 23

Slide 23 text

Q.途中でカラムが増えてたら・・・ https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models A. on_schema_changeの設定に従った挙動をする

Slide 24

Slide 24 text

Q.途中でカラムが増えてたら・・・ https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models A. on_schema_changeの設定に従った挙動をする デフォルトはignoreで何もしない ● 新しく列を追加しても Alterされない ● 既存の列を削除しても Alterされない ※モデルの更新が成功するかは targetのtypeによる。 この挙動はv0時代のもので、おす すめはしない

Slide 25

Slide 25 text

Q.途中でカラムが増えてたら・・・ https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models A. on_schema_changeの設定に従った挙動をする failを指定するとエラーになる 対応方法もちゃんと提示される

Slide 26

Slide 26 text

Q.途中でカラムが増えてたら・・・ https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models A. on_schema_changeの設定に従った挙動をする append_ new_columnsを指定すると ● 新しく列を追加したら Alterされる ● 既存の列を削除しても Alterされない ※削除された列は、 Insertのクエリから 省かれるので、基本的には NULL

Slide 27

Slide 27 text

Q.途中でカラムが増えてたら・・・ https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models A. on_schema_changeの設定に従った挙動をする sync_all_columnsを指定すると ● 新しく列を追加したら Alterされる ● 既存の列を削除したら Alterされる ※当然のごとく 列削除 => 列をもとに戻す としても、元のデータは入ってない

Slide 28

Slide 28 text

Q.途中でカラムが増えてたら・・・ https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models A. on_schema_changeの設定に従った挙動をする 基本的にデフォルト挙動を sync_all_columns もしくは append_new_columns にしてdbt_project.ymlにて 書き換えて置くことをオススメ

Slide 29

Slide 29 text

Q.再処理したくなったら・・・ A.--full-refresh もしくは、頑張る https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models 全部まるまる作り直すなら –full-refresh ログ処理等で、一分のデータだけ処理したいなら macroやpre_hook、varを駆使して頑張る

Slide 30

Slide 30 text

Q.upsertを実現するには・・・ A. incremental_strategyとunique_keyを用いて実現 https://docs.getdbt.com/docs/building-a-dbt-project/building-models/configuring-incremental-models ※incremental_strategyはtargetのtypeによって使える ものが変わる 基本的にはmergeでOK unique_keyを指定すると以下のように deleteしてから insertするようになったりする

Slide 31

Slide 31 text

(具体的にどうしたらいいのか?) 『何もわからない』!!! 通称:ダニング ⹀クルーガー曲線 きっと今この辺 {{ config(materialized=’incremental’) }}

Slide 32

Slide 32 text

基本のmaterializationの4つ ● table ● view ● ephemeral ● incremental 物理テーブルや物理ビューを洗替する 物理的なモノが存在しない 物理テーブルを継続して更新し、運用する

Slide 33

Slide 33 text

基本のmaterializationの4つ ● table ● view ● ephemeral ● incremental 物理テーブルや物理ビューを洗替する 物理的なモノが存在しない 物理テーブルを継続して更新し、運用する 一つの物理テーブルの変更操作を、 1つのモデルに抽象化する 抽象化=ソフトウェア開発のベストプラクティスの一つ

Slide 34

Slide 34 text

基本のmaterializationの4つ ● table ● view ● ephemeral ● incremental 物理テーブルや物理ビューを洗替する 物理的なモノが存在しない 物理テーブルを継続して更新し、運用する 一つの物理テーブルの変更操作を、 1つのモデルに抽象化する 抽象化=ソフトウェア分析のベストプラクティスの一つ incremental、それは・・・

Slide 35

Slide 35 text

基本のmaterializationの4つ ● table ● view ● ephemeral ● incremental 物理テーブルや物理ビューを洗替する 物理的なモノが存在しない 物理テーブルを継続して更新し、運用する 一つの物理テーブルの変更操作を、 1つのモデルに抽象化する 抽象化=ソフトウェア分析のベストプラクティスの一つ incremental、それは・・・ Analytics Engineeringの真髄の一端だった。

Slide 36

Slide 36 text

ご清聴ありがとうございました。

Slide 37

Slide 37 text

以降、ただのネタ

Slide 38

Slide 38 text

同じ結果になります 左と右の違いは・・・drop table if exists … cascade 左は依存先のDB Viewがcascadeドロップされない。

Slide 39

Slide 39 text

ネタ解説 dbt run の挙動は実は以下のような流れになってる dbt run parse (not execute) : DBTの.sqlや.ymlを読み込んだり ref()を解析したりする。 主な成果物として manifest.jsonができる runtime (execute) : 実際にDWHに実行するための .sqlファイルのレンダリング、そして実行する .sqlのレンダリング materializationのレンダリング+実行( DRY RUNで実際にはDWHには何も実行されない) .sqlのレンダリング materializationのレンダリング+実行

Slide 40

Slide 40 text

ネタ解説 dbt run の挙動は実は以下のような流れになってる dbt run parse (not execute) : DBTの.sqlや.ymlを読み込んだり ref()を解析したりする。 主な成果物として manifest.jsonができる runtime (execute) : 実際にDWHに実行するための .sqlファイルのレンダリング、そして実行する .sqlのレンダリング materializationのレンダリング+実行( DRY RUNで実際にはDWHには何も実行されない) .sqlのレンダリング materializationのレンダリング+実行 configの中身が 書き換えられる のはこのだけ DWHにSQLが 実行できるの は、ここだけ

Slide 41

Slide 41 text

ネタ解説 dbt run の挙動は実は以下のような流れになってる dbt run parse (not execute) : DBTの.sqlや.ymlを読み込んだり ref()を解析したりする。 主な成果物として manifest.jsonができる runtime (execute) : 実際にDWHに実行するための .sqlファイルのレンダリング、そして実行する .sqlのレンダリング materializationのレンダリング+実行( DRY RUNで実際にはDWHには何も実行されない) .sqlのレンダリング materializationのレンダリング+実行 configの中身が 書き換えられる のはこのだけ DWHにSQLが 実行できるの は、ここだけ Parseの段階で、DWH上に実際に物理テーブルの存在を確認することはできない macroを使わずに1ファイルでtableもどきを作るには、runtimeの.sqlのレンダリング段階 で、物理テーブルの rowをdeleteする必要。

Slide 42

Slide 42 text

ネタ解説 Parseの段階で、DWH上に実際に物理テーブルの存在を確認することはできない macroを使わずに1ファイルでtableもどきを作るには、runtimeの.sqlのレンダリング段階 で、物理テーブルの rowをdeleteする必要。

Slide 43

Slide 43 text

ネタ解説 Parseの段階で、DWH上に実際に物理テーブルの存在を確認することはできない macroを使わずに1ファイルでtableもどきを作るには、runtimeの.sqlのレンダリング段階 で、物理テーブルの rowをdeleteする必要。 https://github.com/dbt-labs/dbt-core/blob/main/core/dbt/include/global_project/ macros/materializations/models/incremental/is_incremental.sql is_incremental()マクロは、Parse段階では常にFalse Runtime段階で、実際のDWH上の物理テーブルの存在を確認して、 実行時のフラグやmodelの状態もみて、True or Falseを返している。 なので、この.sqlファイルはRuntimeの.sqlのレンダリング時にdeleteが実行される