0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

jsonで特定のキーがない、または余分にあるレコードをスキーマ指定してGlue(Sparkジョブ)で読み込んだ時の挙動

Last updated at Posted at 2023-05-08

はじめに

Glueでjsonをロードしたいことはよくあると思います。
その時、jsonのレコードが全て同じキーで揃っていることが理想です。
ただ、実際のデータは想像よりも汚いものです。キーが揃っていない時、スキーマを指定してGlueでロードするとどうなるかを検証します。

知りたいこと

GlueでSparkのDataFrame(DynamicFrameではない)として、スキーマを指定してjsonをロードした時、そのjsonが以下の時の挙動を確認します。
① 特定のキーがないレコードが含まれる
② 余計なキーがあるレコードが含まれる

前提条件

  • Glue version: 3.0
  • Spark version: 3.1.1
  • jsonファイルはS3に格納
  • name, price, countの3つのカラムを持つスキーマを指定してロード
  • DynamicFrameではなくSparkのDataFrameとしてロード

結論

jsonで特定のキーがないレコードは、そのキーがnullとして読み込まれる
余分に特定のキーがあるレコードは、そのキーが読み込まれず指定されたスキーマのデータだけがロードされる。

実験内容

理想のjson

4つのレコードに、name, price, countのキーが含まれています。
image.png

これを3つのカラムを指定して読み込んだところ、想定通り3つのカラムで4つのレコードが読み込まれました。
image.png

①(特定のキーがないレコードが含まれる)のjson

4レコード目のcountのキーがない状態です。
image.png

これを3つのカラムを指定して読み込んだところ、4レコード目のcountはnullとして読み込まれました。
image.png

②(余計なキーがあるレコードが含まれる)のjson

3レコード目にupdate_dateという余計なキーが追加されています。
image.png

これを3つのカラムを指定して読み込んだところ、3レコード目のupdate_dateというキーは読み込まれませんでした。
image.png

追加実験

①(特定のキーがないレコードが含まれる)のとき、スキーマの指定では"count"のnullable = Trueとoptionで指定していました。つまり、nullを許容する状態でした。
これをFalseと指定してみましたが、結局スキーマとしてはnullable = trueの状態でした。
image.png

スキーマでnullableをFalseと指定しても、結局内部的にはtrueになってしまうので、スキーマを補正しないといけないようです。

おわりに

このあたりのスキーマに関するところは、Sparkを使うときに型の指定とともに悩まされるポイントですね。
これに関しては、Glueのデータカタログ + DynamicFrameで扱う方がやりやすそうだなと感じました。
SparkのDataFrameの処理を使いたい場合も、
DynamicFrameでデータカタログからロード ⇒ SparkのDataFrameで処理 ⇒ DynamicFrameでデータカタログに書き込み
という変換が可能です。
ただ、どうしてもSparkのDataFrameとしてロードさせたい(Choice型を最初から持ちたくない、など)場合は今回のようにスキーマを指定してあげたほうが無難そうです。

参考

実行したコードを以下に記載しておきます。
実験では、以下のコードのロードのパスを変えているだけです。

from pyspark.sql.types import *

schema = StructType([
      StructField("name",StringType(),True),
      StructField("price",IntegerType(),True),
      StructField("count",IntegerType(),True)
])

df_with_schema = spark.read.schema(schema).json("s3://sample-bucket/correct/")
df_with_schema.show()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?