【ITニュース解説】dbt+Athenaでテーブルのオーバーライトをやってみた
2025年09月18日に「Qiita」が公開したITニュース「dbt+Athenaでテーブルのオーバーライトをやってみた」について初心者にもわかりやすく解説しています。
ITニュース概要
dbtはSQLを使い、データ処理の流れ(パイプライン)を構築するツールだ。この記事では、dbtとAmazon Athenaを組み合わせ、既存のデータベーステーブルを新しいデータで上書きする「オーバーライト」を試した体験を解説。dbtとAthenaの組み合わせ特有の挙動を紹介している。
ITニュース解説
データ分析の現場では、生の状態のデータをそのまま使うことは少なく、分析しやすい形に加工する「データ変換」という作業が非常に重要になる。このデータ変換のプロセスを効率的に、かつ確実に実行するためのツールが「dbt」だ。dbtはSQLというデータベース操作言語を使って、データの変換処理を定義できる。これにより、複雑なデータ加工のワークフローをSQLで記述し、自動化された「データパイプライン」を構築できる。データパイプラインとは、データが入力され、複数の処理ステップを経て最終的な出力へと流れていく一連の流れを指す。dbtでは、この処理の流れを「DAG(有向非巡回グラフ)」という形式で表現する。DAGは、各データ変換ステップがノードとして繋がり、データの流れが一方通行の矢印で示される図のようなもので、処理の依存関係が明確になる。dbtが裏側で何をしているかというと、定義されたSQLモデルに基づいて、データベースに対してデータの作成(CREATE TABLE)や削除(DROP TABLE)といったSQLクエリを発行し、実際にデータを操作している。
次に、このdbtと組み合わせて使われることの多いデータ分析サービスとして、「Amazon Athena」がある。AthenaはAWS(アマゾンウェブサービス)が提供する「サーバーレス」なクエリサービスだ。サーバーレスとは、ユーザーがサーバーの起動や管理といったインフラの運用に手間をかけることなく、必要な時に必要なだけコンピューティングリソースを利用できる仕組みを指す。Athenaの大きな特徴は、データをAmazon S3というクラウドストレージに保存しておけば、そのS3上のデータを直接SQLで分析できる点にある。つまり、わざわざデータを専用のデータベースにロードしなくても、S3に置かれたCSVやParquetといったファイル形式のデータを、データベースのテーブルとして扱えるのだ。
ここで重要なのが、Athenaのテーブル構造の特殊性だ。一般的なリレーショナルデータベースでは、テーブルの定義(スキーマ)と実際のデータは一体となって管理されている。しかし、Athenaの場合、テーブルの定義は「AWS Glueデータカタログ」というサービスに保存され、実際のデータファイルはS3に保存されるというように、これらが明確に分離している。Glueデータカタログは、いわばS3に散らばるデータファイルがどのような構造をしているか、どこに保存されているか、といった情報をまとめた「目次」のような役割を果たす。
dbtとAthenaを組み合わせて使う際に、このテーブル構造の分離が特定の課題を引き起こすことがある。それは「テーブルのオーバーライト」、つまり既存のテーブルを新しいデータや定義で完全に上書きして再作成する際に発生する問題だ。dbtでテーブルをオーバーライトする典型的な方法は、まず既存のテーブルを削除し(DROP TABLE)、次に新しいテーブルを作成する(CREATE TABLE)という手順を踏む。dbtはこのDROP TABLE文をAthenaに発行する。
しかし、前述の通りAthenaではテーブル定義と実データが分離しているため、このDROP TABLE文が実行された際に削除されるのは、Glueデータカタログに登録されているテーブルの定義情報だけだ。S3に保存されている実際のデータファイルは、DROP TABLE文では削除されない。結果として、dbtが新しいテーブルをCREATE TABLE文で作成したとしても、S3には古いテーブルのデータファイルがそのまま残り続けることになる。
この状態が続くと、いくつかの問題が発生する可能性がある。まず、S3上に不要な古いデータが蓄積され続けるため、ストレージのコストが無駄にかさんでしまう。さらに深刻なのは、データの一貫性が損なわれる可能性だ。場合によっては、古いデータファイルと新しいデータファイルが混在し、Athenaでクエリを実行した際に、意図しない古いデータまで読み込まれてしまったり、データ重複が発生したりして、分析結果が誤ってしまう恐れがある。これは、データに基づいた意思決定にとって非常に危険な状況だ。
このような問題を解決するためには、dbtがテーブルをオーバーライトする際に、S3上の既存のデータファイルも確実に削除する仕組みを導入する必要がある。そのためのアプローチの一つとして、dbtの「フック」という機能を利用する方法がある。フックとは、dbtがSQLを実行する前や後にカスタムの処理を挟み込むことができる機能だ。具体的には「pre-hook」という、テーブルを作成する前の段階で実行されるフックを使う。
このpre-hookの内部で、S3のデータを削除するコマンドを実行するように設定する。S3のデータを削除するには、通常AWS CLI(コマンドラインインターフェース)のaws s3 rm --recursiveといったコマンドを使う。しかし、dbtは基本的にSQLしか実行しないため、そのままでは外部のコマンドを実行できない。そこで、dbtの少し高度な機能である「executeマクロのオーバーライド」というテクニックを用いる。
executeマクロとは、dbtがSQL文をデータベースに実際に発行する際に使われる内部マクロの一つだ。このマクロを、プロジェクト独自の定義で上書きすることで、SQLの実行だけでなく、Pythonの機能を使って外部コマンドを実行できるようにカスタマイズできる。具体的には、このオーバーライドされたexecuteマクロの中で、Jinjaテンプレートというdbt内でPythonライクな処理を記述できる言語を使って、現在のテーブルのスキーマ名やテーブル名を動的に取得し、その情報に基づいてS3上の正確なパスを特定する。そして、特定したS3パスに対してAWS CLIの削除コマンドを実行する、という流れだ。
これにより、dbtがテーブルを作成する前に、該当するS3パスにある古いデータファイルを確実に削除し、その後に新しいテーブルが作成される。この方法によって、dbt+Athena環境でのテーブルオーバーライト時のデータ不整合や無駄なストレージコストの問題を解決できる。
ただし、このアプローチはdbtの内部挙動を深く理解する必要があり、executeマクロのオーバーライドは慎重に行う必要がある。外部コマンドの実行は、セキュリティリスクや環境依存性(例えば、dbtが実行される環境にAWS CLIがインストールされている必要がある)を伴うため、実装には十分な注意とテストが求められる。よりシンプルで堅牢な方法として、S3のライフサイクルポリシーを使って古いファイルを自動削除したり、AWS Lambda関数やAWS Glueジョブといった別のAWSサービスを活用してS3のデータ削除を管理したりすることも検討できるだろう。しかし、dbtのパイプライン内で完結させたい場合には、このpre-hookとexecuteマクロのオーバーライドを用いた方法が強力な解決策となる。