PySpark设置timestampFormat仍无法自动推断时间戳类型问题
问题场景
有如下JSON数据:
{"created_at":"2022-01-02 12:17:43.399 UTC","updated_at":"2022-01-02 12:17:43.399 UTC"}
使用Spark 3.3.2执行以下代码读取:
read_df = spark \ .read \ .option("timestampFormat", "yyyy-MM-dd HH:mm:ss.SSS 'UTC'") \ .option("inferSchema", "true") \ .json(path)
但自动推断出的Schema里,created_at和updated_at被识别成了字符串类型:
root |-- created_at: string (nullable = true) |-- updated_at: string (nullable = true)
手动用to_timestamp(col("created_at"), "yyyy-MM-dd HH:mm:ss.SSS 'UTC'")转换能成功,但因为要复用读取函数处理不同Schema的文件,不想手动指定Schema,需要找出自动推断失败的原因和解决办法。
原因分析
Spark的JSON数据源在自动推断Schema时,默认不会启用timestampFormat参数——这个参数只有在明确指定字段为时间戳类型(比如手动定义Schema),或者配合enableDateTimeParsingFallback参数调整解析逻辑时才会生效。
开启inferSchema=true后,Spark会先尝试用默认时间格式匹配字段内容,而你的时间字符串带了UTC时区后缀,不符合Spark默认的时间戳格式(默认是yyyy-MM-dd'T'HH:mm:ss.SSSXXX这类不带显式时区字符串的格式),所以被识别成了字符串。
解决办法
通过添加额外配置,让Spark推断Schema时用指定的时间格式解析:
1. 启用enableDateTimeParsingFallback并指定时间格式
修改读取代码,添加enableDateTimeParsingFallback参数设为false,强制Spark使用你定义的格式解析时间字符串:
read_df = spark \ .read \ .option("timestampFormat", "yyyy-MM-dd HH:mm:ss.SSS 'UTC'") \ .option("inferSchema", "true") \ .option("enableDateTimeParsingFallback", "false") \ .json(path)
这个参数会关闭Spark默认的时间解析回退逻辑,强制用你设定的格式尝试解析,这样Spark推断Schema时就会把匹配格式的字段识别为TimestampType。
2. 配合multiLine参数(按需添加)
如果你的JSON文件是多行模式(每个JSON对象占一行),可以加上.option("multiLine", "true"),确保Spark正确读取每个对象,避免解析异常影响Schema推断。
执行修改后的代码后,Schema会被正确推断为:
root |-- created_at: timestamp (nullable = true) |-- updated_at: timestamp (nullable = true)
内容的提问来源于stack exchange,提问作者Tizianoreica

