Fixing Athena Query Length Errors in dbt-elementary with Chunking

環境

  • dbt-athena
  • dbt-elementary
  • Athenaは boto3経由で実行

やりたかったこと

dbt runelementary の流れで、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クエリがログに出力されていました

つまり:

  • elementarydbt 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-elementarydbt run の実行結果をGlue Tableに保存するが、長すぎるクエリで失敗することがある
  • dbt_project.ymlinsert_rows_methoddbt_artifacts_chunk_size を設定することで 分割挿入が可能