我有一段代码,最后,我将数据帧写入镶木地板文件中。
逻辑上,数据框有时可能为空,因此出现以下错误。
df.write.format("parquet").mode("overwrite").save(somePath)
org.apache.spark.sql.AnalysisException: Parquet data source does not support null data type.;
当我打印“ df”的架构时,我得到以下信息。
df.schema
res2: org.apache.spark.sql.types.StructType =
StructType(
StructField(rpt_date_id,IntegerType,true),
StructField(rpt_hour_no,ShortType,true),
StructField(kpi_id,IntegerType,false),
StructField(kpi_scnr_cd,StringType,false),
StructField(channel_x_id,IntegerType,false),
StructField(brand_id,ShortType,true),
StructField(kpi_value,FloatType,false),
StructField(src_lst_updt_dt,NullType,true),
StructField(etl_insrt_dt,DateType,false),
StructField(etl_updt_dt,DateType,false)
)
是否有一种变通方法是仅使用架构写入空文件,或者在为空时根本不写入文件? 谢谢
答案 0 :(得分:1)
'还是在空的时候根本不写文件?'检查df是否不为空,然后只写它。
if (!df.isEmpty)
df.write.format("parquet").mode("overwrite").save("somePath")
答案 1 :(得分:1)
您得到的错误与您的数据框为空的事实无关。我看不到保存一个空数据框的意义,但是您可以根据需要进行操作。如果您不相信我,请尝试以下操作:
val schema = StructType(
Array(
StructField("col1",StringType,true),
StructField("col2",StringType,false)
)
)
spark.createDataFrame(spark.sparkContext.emptyRDD[Row], schema)
.write
.format("parquet")
.save("/tmp/test_empty_df")
您会收到此错误,因为其中一列为NullType,并且抛出的异常表明"Parquet data source does not support null data type"
我不确定您为什么会有Null类型的列,但是通常在您从源中读取数据并让spark推断模式时会发生这种情况。如果该源中有一个空列,spark将无法推断该模式,并将其设置为null类型。
如果发生这种情况,我的建议是指定读取模式。
如果不是这种情况,则可能的解决方案是将NullType的所有列都转换为与拼花地板兼容的类型(如StringType)。这是有关如何执行此操作的示例:
//df is a dataframe with a column of NullType
val df = Seq(("abc",null)).toDF("col1", "col2")
df.printSchema
root
|-- col1: string (nullable = true)
|-- col2: null (nullable = true)
//fold left to cast all NullType to StringType
val df1 = df.columns.foldLeft(df){
(acc,cur) => {
if(df.schema(cur).dataType == NullType)
acc.withColumn(cur, col(cur).cast(StringType))
else
acc
}
}
df1.printSchema
root
|-- col1: string (nullable = true)
|-- col2: string (nullable = true)
希望这会有所帮助