【トラブル】AWS Glue上で エラー「Dynamic partition strict mode requires ...」が発生する

■ はじめに

https://dk521123.hatenablog.com/entry/2021/05/15/130604

を調査している際に、以下「参考サイト」で
『GlueのSparkバージョンが2.3.0になれば』って記載されていた。

で、以下のAWS Glue の公式サイト

https://docs.aws.amazon.com/ja_jp/glue/latest/dg/add-job.html

で確認したところ、
「Spark 2.4.3」となっていたので、insertInto を試してみた。
しかし、エラー「Dynamic partition strict mode requires ...」が
発生したので、その際のトラブルシュートをメモしておく。

参考サイト
https://yomon.hatenablog.com/entry/04/glueoverwrite

より抜粋
~~~~~~~~
または、GlueのSparkバージョンが2.3.0になれば(現状は2.2.1)、
この方法も使えるようになるので、少しシンプルに書けるようになります。

spark.conf.set("spark.sql.sources.partitionOverwriteMode","dynamic")
data.write.mode("overwrite").insertInto("partitioned_table")
~~~~~~~~

目次

【1】エラー内容
【2】エラーが発生したコード
【3】解決案

【1】エラー内容

Caused by: org.apache.spark.SparkException:
Dynamic partition strict mode requires
 at least one static partition column.
To turn this off set hive.exec.dynamic.partition.mode=nonstrict

【2】エラーが発生したコード

NGコード

import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

args = getResolvedOptions(sys.argv, ['JOB_NAME'])
job_name = args['JOB_NAME']

print(f"Start {job_name}!!")

spark_context = SparkContext()
glue_context = GlueContext(spark_context)
spark = glue_context.spark_session

job = Job(glue_context)
job.init(job_name, args)

# create glue dynamicframe
# Ref to https://www.reddit.com/r/aws/comments/e20ggy/writing_from_dynamicframe_gluepyspark_to_s3_is/  
dynamic_frame= glue_context.create_dynamic_frame_from_options(
  connection_type="s3",
  connection_options={"paths": ["s3://your-bucket-name/xxx/your-folder"]},
  format="csv",
  format_options={
    "withHeader": True,
    "separator": ","
  }
)
spark.conf.set("spark.sql.sources.partitionOverwriteMode", "dynamic")
# ★ここで発生★
dynamic_frame.toDF().write \
  .mode("overwrite") \
  .insertInto("partitioned_table")

job.commit()

【3】原因

以下のサイトに、原因および対応方法が記載されていた。

https://knowledge.informatica.com/s/article/625439?language=en_US

より抜粋
~~~~~~~~
この問題は、
動的パーティション化プロパティが設定されていない場合に発生します。
~~~~~~~~

【4】解決案

https://knowledge.informatica.com/s/article/625439?language=en_US

より抜粋
~~~~~~~~
Solution
​この問題を解決するには、
Administrator Console の接続タブにて
CCO(Cluster Configuration Object) のhive_site_xml に
次のプロパティを設定します。
 
hive.exec.dynamic.partition=true
hive.exec.dynamic.partition.mode=nonstrict
~~~~~~~~
を参考にコードを修正した。

OKコード

spark.conf.set("spark.sql.sources.partitionOverwriteMode", "dynamic")

# ★この行を追加★
spark.conf.set("hive.exec.dynamic.partition", "true")
spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")

dynamic_frame.toDF().write \
  .mode("overwrite") \
  .insertInto("partitioned_table")

おまけ

ちなみに、
以下のように partitionBy() で対応できないかなーっと思って実行したら
以下のエラー内容で対応できなかった。

NGコード

dynamic_frame.toDF().write \
  .mode("overwrite") \
  .partitionBy('partitioned_key') \
  .insertInto("partitioned_table")

エラー内容

org.apache.spark.sql.AnalysisException:
'insertInto' can't used together with partitionBy().
Partition columns have already been defined for the table.
It is not necessary to use partitionBy().

【概要】
既にパーティションキーが定義されているんだから、
partitionBy() は必要ない

関連記事

AWS Glue ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/10/01/221926
PySpark ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2019/11/14/221126
PySpark ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2021/04/03/004254
PySpark でエラー「Exception: It appears ...」が表示された
https://dk521123.hatenablog.com/entry/2020/07/10/192404
PySpark でエラー「Total size ... is bigger than spark.driver.maxResultSize」が発生する
https://dk521123.hatenablog.com/entry/2021/04/22/131849
PySpark でエラー「Exception: It appears ...」が表示された
https://dk521123.hatenablog.com/entry/2019/10/01/221926
AWS Glue上で saveAsTextFile() を使ったら エラー「DirectOutputCommitter not found」が発生する
https://dk521123.hatenablog.com/entry/2021/05/18/185420