Spark:写入Parquet文件时无法理解的行为-数据类型

goo*_*ead 3 java scala apache-spark

我有这样的csv记录:

--------------------------- 
name | age | entranceDate | 
---------------------------
Tom  | 12  | 2019-10-01   |
---------------------------
Mary | 15  | 2019-10-01   | 
Run Code Online (Sandbox Code Playgroud)

我使用定制模式从CSV读取并将其转换为DataFrame:

public static StructType createSchema() {
    final StructType schema = DataTypes.createStructType(Arrays.asList(
            DataTypes.createStructField("name", DataTypes.StringType, false),
            DataTypes.createStructField("age", DataTypes.StringType, false),
            DataTypes.createStructField("entranceDate", DataTypes.StringType, false)
    ));
    return schema;
}


sqlContext.read()
                .format("com.databricks.spark.csv")
                .option("inferSchema", "false")
                .option("delimiter", FIELD_DELIMITER)
                .option("header", "false")
                .schema(schema)
                .load(pathToMyCsvFile);
Run Code Online (Sandbox Code Playgroud)

现在,我想将此数据帧写到我的hdfs的木地板上:

String[] partitions =
new String[] {
  "name",
  "entranceDate"
};

df.write()
.partitionBy(partitions)
.mode(SaveMode.Append)
.parquet(parquetPath);
Run Code Online (Sandbox Code Playgroud)

但是当我在spark-shell中检查实木复合地板的架构时:

sqlContext.read.parquet("/test/parquet/name=Tom/entranceDate=2019-10-01/").printSchema()
Run Code Online (Sandbox Code Playgroud)

它显示entranceDateis类型Date。我不知道那是怎么回事?我已经指定该字段应该为String,如何将其自动转换为Date

--------------

编辑:我做了一些测试,发现只有.partitionBy(partitions)在编写时才将其转换为日期。如果删除此行并打印架构,它将显示entranceDateis 的类型String

小智 5

我会说是因为自动模式推断机制。Spark文档页面

请注意,分区列的数据类型是自动推断的。当前,支持数字数据类型,日期,时间戳和字符串类型。

有时用户可能不希望自动推断分区列的数据类型。对于这些用例,可以使用来配置自动类型推断 spark.sql.sources.partitionColumnTypeInference.enabled,默认为true