如何强制 CSV 的 inferSchema 将整数视为日期(使用 "dateFormat" 选项)?

How to force inferSchema for CSV to consider integers as dates (with "dateFormat" option)?

我使用 Spark 2.2.0

我正在读取一个csv文件如下:

val dataFrame = spark.read.option("inferSchema", "true")
                          .option("header", true)
                          .option("dateFormat", "yyyyMMdd")
                          .csv(pathToCSVFile)

此文件中有一个日期列,对于这一特定列,所有记录的值都等于 20171001

问题是 spark 推断此列的类型是 integer 而不是 date。当我删除 "inferSchema" 选项时,该列的类型是 string.

此文件中没有 null 个值,也没有任何格式错误的行。

这个问题的 reason/solution 是什么?

在这种情况下,由于格式不明确,您根本无法依赖模式推断。

因为输入可以被解析为 IntegerType (或任何更高精度的数字格式)以及 TimestamType 并且前者具有更高的优先级(内部 Spark 尝试 IntegerType - > LongType -> DecimaType -> DoubleType -> TimestampType) 推理机制永远不会达到 TimestampType 的情况。

具体而言,启用模式推理后,Spark will call tryParseInteger, which will correctly parse the input and stop. Subsequent call will match the second case 并在同一个 tryParseInteger 调用中完成。

如果我的理解是正确的,那么code意味着以下类型推断顺序(首先检查第一种类型):

  • NullType
  • IntegerType
  • LongType
  • DecimalType
  • DoubleType
  • TimestampType
  • BooleanType
  • StringType

因此,我认为问题在于 20171001 在考虑 TimestampType(使用 timestampFormat 而不是 dateFormat 选项之前匹配 IntegerType

一种解决方案是定义模式并将其与 schema 运算符(属于 DataFrameReader)一起使用,或者让 Spark SQL 推断模式并使用 cast 运算符.

如果字段数不多,我会选择前者