環境
- dbt-athena
- dbt-elementary
- Athenaは boto3経由で実行
やりたかったこと
dbt run
→ elementary
の流れで、dbtの実行ログやメタデータをGlue Tableに保存するという仕組みを構築中でした
このとき elementary が実行するクエリ(INSERT INTO dbt_run_results
など)は、dbt runで実行されたSELECTクエリの内容を含むため、かなりの長文になります
問題発生
dbt run
までは普通に成功
しかしその直後、elementaryの処理で下記のエラーが発生:
botocore.errorfactory.InvalidRequestException: An error occurred (InvalidRequestException) when calling the StartQueryExecution operation:
Your query has exceeded the maximum query length of 262144 bytes.
Please reduce the length of your query and try again.
If you continue to see this issue after reducing your query length, contact customer support for further assistance.
Athenaにはクエリ文字列の最大長(262,144 bytes)があるようで、それに引っかかっていました
調査したこと
最初は「どこで何が失敗してるのか?」すらわからず、dbt build --debug
で実行してみました。
するとログに以下のような出力が:
08:14:18 Elementary: Inserting 179 rows to table "awsdatacatalog"."main_elementary"."dbt_run_results"
08:14:20 Elementary: [1/2] Running insert query.
その直後から、複数の長大なSELECT文が連結されたINSERTクエリがログに出力されていました
つまり:
elementary
がdbt run
の結果をGlue Tableに登録しようとしている- クエリが2回に分割されているが、それでも長すぎる
- Athenaのクエリ文字数制限に引っかかって失敗している
という流れでした
解決方法:クエリをもっと細かく分割させる
調べてみると、elementary側でINSERTクエリをチャンク分割する設定が用意されていましたdbt_project.yml
に以下のような設定を追加:
...
clean-targets:
- "target"
- "dbt_packages"
vars:
insert_rows_method: chunk # チャンク挿入を有効に
dbt_artifacts_chunk_size: 50 # クエリ長を調整(行数ベース)
...
これにより、INSERTクエリがより小さく分割されるようになります
結果:エラー解消&分割数も増えた
再度実行したところ、Athenaのクエリ長エラーは発生せず、正常に処理が完了しました
ログを見ると:
03:13:27 Elementary: Inserting 179 rows to table "awsdatacatalog"."main_elementary"."dbt_run_results"
03:13:29 Elementary: [1/4] Running insert query.
先ほどは [1/2]
だったのが、今回は [1/4]
に分割されていて、ちゃんと設定が効いていることが確認できました
まとめ
- Athenaには クエリ長の上限(262,144 bytes) がある
dbt-elementary
はdbt run
の実行結果をGlue Tableに保存するが、長すぎるクエリで失敗することがあるdbt_project.yml
にinsert_rows_method
とdbt_artifacts_chunk_size
を設定することで 分割挿入が可能