본문 바로가기
Spark

[Spark] json -> parquet로 저장시 스키마 충돌 문제 해결

by 초이MS 2021. 10. 6.

목적

  • json으로 저장된 파일을 partition을 추가하여 parquet로 저장하려한다.
  • 이때, json 내에 빈 array가 있을 경우 inferSchema로 인해 array(string)의 스키마로 표현된다.
  • 이 경우 다른 파일에서 array내에 struct 등의 다른 값이 들어올 경우 에러가 발생한다.
  • pre-defined된 schema가 있다면 좋겠으나 필자의 경우는 그렇지 못하였다.
  • 필자에게 발생한 에러메시지는 아래와 같다.
java.lang.ClassCastException: optional binary element (UTF8) is not a group
	at org.apache.parquet.schema.Type.asGroupType(Type.java:207)
	at org.apache.spark.sql.execution.datasources.parquet.ParquetReadSupport$.org$apache$spark$sql$execution$datasources$parquet$ParquetReadSupport$$clipParquetType(ParquetReadSupport.scala:200)
    ...

해결

  1. 필자의 경우 json 파일을 읽어 데이터를 처리 후 parquet로 저장하는 과정을 거쳐야했다.
  2. json을 읽는때에 'dropFieldIfAllNull'옵션을 추가해서 모든 빈 값들을 전부 드랍한다. 이 경우 추후 데이터를 읽을 때 mergeSchema를 하기 유리하다.
    df = spark.read.option('dropFieldIfAllNull', True).json(${json_data_path})
  3. 추후 데이터를 읽을 때는 아래와 같이 데이터를 읽어들였다.
    df = spark.read.option("mergeSchema", "true").parquet(${parquet_data_path})

참고

https://stackoverflow.com/questions/60297547/handling-empty-arrays-in-pyspark-optional-binary-element-utf8-is-not-a-group

반응형

댓글