BI LAB データ活用研究所 - INSIGHT LAB

【dbt×Snowflake】External Network Accessによるデータロードをdbtで管理する

作成者: uta|2023年12月13日

本記事はdbt Advent Calendar 2023の13日目の記事になります。

はじめに

新卒からデータ分析基盤を管理を行ううちに、気づけばミニマリストになってしまいました。「いらないものは買わないor捨てる」「よく使うものはすぐに使えるようにしておく」が私生活に浸透しています。

本記事は、そんなミニマリストには嬉しい?「APIを用いたデータロードであれば、ELTをSnowflakeとdbtだけで完結できてしまうかも」という趣旨の内容になります。

 

背景

先日、SnowflakeでExternal Network Access(以降、ENA)という機能がパブリックプレビューになりました。詳細については、以前作成した記事を参考にしてください。
https://knowledge.insight-lab.co.jp/snowflake/-external_access_integration_notion_api

ENAは、Snowflakeから外部APIでセキュアにアクセスすることができる機能です。利用できるAPIは幅広く、データロードからデータ送信、データ基盤と全く関係のないAPIですら実行することができます。

現在担当するプロジェクトで、このENAを用いたデータロードを行うパイプライン構築検証をしており、並行してdbtCloudの導入も進めています。

元々、Snowflakeのタスクで構築されたパイプラインに乗せる予定だったのですが、一部パイプラインがdbtCloudに移行されているため、どうせならdbtのパイプラインで実装する方針になりました。

 

パイプライン構成(仮)

以前の記事で作成したUDFを例にNotion上のデータをロードするモデルを作成してみます。
https://knowledge.insight-lab.co.jp/snowflake/-external_access_integration_notion_api

データ取得はUDFから返される半構造化データをINSERT INTOでテーブルに格納する形になるため、モデルのSELECT句には、データを格納するVARIANTと、ロードを実行した日と日時のカラムを最低限設定します。

また、実行の度にロードさせるため、materiaizedはincrementalとし、incremental_strategyはappendで設定します。(データ量が多い場合は基準となるカラムで増分更新を)

これだけで、モデルが実行される度に外部ネットワークにアクセスし、取得したデータがRAWテーブルロードされます。

 

後続モデルは適宜レイヤー構成に従って、variantデータの展開やデータクレンジングなどtransformを行うモデルを実装していきます。(余談ですが、NotionAPIから返されるJSON構成がまた変更されていたらしく、苦労して作ったJSON構造化用のオリジナルマクロがまた機能しなくなりました…。)

 

モデルで管理するメリット

dbtの立ち場としてはデータ変換ツールなので、データロードはFivetranやtroccoなどのETLツールが必要になります。しかし、ENAによるロードであればETLツール不要でSnowflakeとdbtでELTが成り立ちます。

もちろんAPIで取得できないデータに関しては、ETLツールによるExtractが必要なので、完全にETLツール不要とはなりません。ただ、ELTがdbt上で完結すると、オーケストレーションが実質dbtのみで成立し、仮にロードでエラーが発生した場合、dbt retryの実行によってEからTまでのリカバリが一気通貫で行うことができます。

後述しますがdbtでUDFも管理できるので、データロード処理もモデルと同様にバージョン管理やテストができ、全体的にみても管理・運用は楽になりそうです。

 

課題

メリットがある反面、解決しなければいけない課題もいくつかあります。そのひとつがオブジェクトの管理です。ENAにはシークレット、ネットワークルール、外部アクセス統合、UDFの計4オブジェクトが必要になります。

先3つは変更頻度が低くかつ厳重に管理しなければいけないオブジェクトなので、Snowflake側で管理することになると思います。

UDFについても、Snowflake側で管理するものと考えていましたが、ちょうどアドベントカレンダーの9日目の記事に、dbtでUDFを管理する方法が共有されていました。(助かります...!)

UDFもSnowflakeで直接管理してしまうと、DWHとdbtの間で差分が生じてしまうリスクなどもありました。しかし、マクロで実装することで、ロードモデルのpre_hookにUDF作成用のマクロを設定すれば、差分は生まれずテストやバージョン管理も行えるのでこの管理方法も試してみたいなと思います。

 

おわりに

dbtCloud導入前は、dbtに対してリネージュが見れるツールというだけの印象でしたが、導入しつつある今では、dbtが無い世界は考えられないですし、別のプロジェクトにも導入したいと思えるほど強力なツールです。

そんなdbtも、次々と新しい機能をリリースしていますが、DWHの新しい機能によってさらに強化されることも同時に理解しました。

まだ手を出せていない「dbt Mesh」や「Semantic Layer」もうまく活用して、パイプラインを整理してデータ活用に頭を悩ませることができる環境を整えていきたいと思います。