【问题标题】:Different types of data in a same column in Parquet partitionParquet分区中同一列中不同类型的数据
【发布时间】:2020-07-15 00:33:51
【问题描述】:

我在从 S3 读取 PARQUET 文件时出错,原因是“final_height”列在同一个分区中有 String 和 Double 类型。有关信息,parquet 文件中有 20 多列。我得到的错误是:

ERROR 1: Failed merging schema of file ".../part1.gz.parquet":

ERROR 2: Caused by: org.apache.spark.SparkException:
Failed to merge fields 'final_height' and 'final_height'. Failed to merge incompatible data types double and string

ERROR 3: com.databricks.sql.io.FileReadException:
Error while reading file ".../part1.gz.parquet".
Parquet column cannot be converted. Column: [final_height], Expected: StringType, Found: DOUBLE

ERROR 4: com.databricks.sql.io.FileReadException:
Error while reading file ".../part1.gz.parquet".
Parquet column cannot be converted. Column: [final_height], Expected: DoubleType, Found: BINARY

ERROR 5: org.apache.spark.sql.execution.datasources.SchemaColumnConvertNotSupportedException

"part1.gz.parquet" 有 X 列的 String 数据和 "part2.gz.parquet" 时找到了一些解决方案在同一列中有双重数据。但是,当在同一分区中发现同一列中的不同类型时,它们不起作用

试过了:

  • 使用 mergeSchema 和 inferSchema 选项读取 (出现错误 1 ​​和 2)
  • 使用预定义的手动模式读取“final_height”列的字符串类型(出现错误 3 和 5)
  • 使用 Double 类型的预定义手动模式读取“final_height”列 (出现错误 4 和 5)

希望有一些解决方案:)

谢谢!

【问题讨论】:

    标签: scala apache-spark amazon-s3 parquet databricks


    【解决方案1】:

    理想的方法是将整个数据帧读取为 Binary (Array[Byte]) 数据类型,然后将相应的值转换为它们兼容的数据类型,但是,Spark 不允许将 Double 数据类型读取为 Binary 数据类型。因此无法继续采用这种方法。

    可以将 Spark 属性“spark.sql.files.ignoreCorruptFiles”设置为 true,然后读取具有所需架构的文件。与指定架构不匹配的文件将被忽略。生成的数据集仅包含来自与指定架构匹配的文件中的数据。因此读取两个数据帧,一个是 String 数据类型,另一个是 Double 数据类型,然后将它们中的任何一个转换为单个数据类型,然后最后合并它们。

    val stringSchema = StructType(StructField("final_height", StringType, false) :: Nil)
    val doubleSchema = StructType(StructField("final_height", DoubleType, false) :: Nil)
    
    spark.conf.set("spark.sql.files.ignoreCorruptFiles", "true")
    
    val stringDF = spark.read.schema(stringSchema).parquet("path/")
    val doubleDF = spark.read.schema(doubleSchema).parquet("path/")
    //Cast to compatible type
    val doubleToStringDF = doubleDF.select(col("final_height").cast(StringType))
    
    val finalDF = stringDF.union(doubleToStringDF)
    

    【讨论】:

    • 如何处理列中具有空值的记录,以便使用模式读取数据帧并创建重复项。
    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 2017-03-07
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 2016-11-24
    • 2020-12-08
    相关资源
    最近更新 更多