SparkSQL存储数据到Parquet:AnalysisException: Parquet data source does not support null data type.

使用SparkSQL(2.4版本)往存储格式为parquet的Hive分区表中存储NullType类型的数据时报错:

org.apache.spark.sql.AnalysisException: Parquet data source does not support null data type.

虽然在Stack OverFlow上找到了类似的问题,但没有具体阐明到底是什么原因导致了这种问题以及如何解决?

1.场景模拟

1)创建temp view:test_view

sparkSession.sql(
      """
        |select 1 as id, null as name
      """.stripMargin
      ).createOrReplaceTempView("test_view")

2)打印test_view的schema信息

-- id为integer类型,name对应到Spark SQL内部字段数据类型即位NullType
root
 |-- id: integer (nullable = false)
 |-- name: null (nullable = true)

3)将test_tab中数据存入Hive分区表test_partition_tab的分区partitionCol=20201009中

df.write.mode(SaveMode.Overwrite).format("parquet").save("/bigdatalearnshare/test_partition_tab/partitionCol=20201009")

4)报错信息
在这里插入图片描述

2. 问题分析

根据报错信息,提示Parquet数据源不支持null type类型的数据。既然是保存数据,我们很容易联想到FileFormatWriter,再结合错误信息:

org.apache.spark.sql.execution.datasources.FileFormatWriter$.write(FileFormatWriter.scala:100

对应的源码为:

DataSourceUtils.verifyWriteSchema(fileFormat, dataSchema)

debug进去,看看这个方法究竟干了什么?
在这里插入图片描述

根据源码分析可知,上述程序中SparkSQL在保存数据时会对数据的schema进行校验,并且不同的存储格式(parquet、csv、json等)支持的数据类型会有所不同,以parquet为例,查看源码:

在这里插入图片描述

3. 解决方案

-- 使用insert sql进行数据的保存
insert overwrite table test_partition_tab partition(partitionCol=20201009) select * from test_view;
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页