首页 > 解决方案 > spark在写入json时截断时间戳

问题描述

当将 Spark DataFrame 的时间戳列写入 JSON 时,微秒会被截断:

val df = Seq("2019-09-30 00:08:27.272846").toDF("dt").select(col("dt").cast("timestamp"))
df.show(false) // prints 2019-09-30 00:08:27.272846
df.write.json("/tmp/spark/dt")
val dff = spark.read.json("/tmp/spark/dt")
dff.show(false) // prints 2019-09-30T00:08:27.272Z

这是预期的行为吗?

https://www.zepl.com/viewer/notebooks/bm90ZTovL2R2aXJ0ekBnbWFpbC5jb20vNGFkZGI1ZDEyZTFlNDJmNTkwMzIyNDg1ODc3ZGI0ZTUvbm90ZS5qc29u

标签: dataframeapache-sparktimestamp

解决方案


是的,这是预期的行为!

当我们timestamp type在将 json 文件写入 HDFS 位置时转换为时,火花会截断并仅保留3 digits in millisecs.

如何在不截断的情况下获取列值?

向 HDFS投射string type和写入数据。

val df = Seq("2019-09-30 00:08:27.272846").toDF("dt").select(col("dt").cast("string"))
df.write.json("/tmp/spark/dt")
val dff = spark.read.json("/tmp/spark/dt")
dff.show(false)

Result:

+--------------------------+
|dt                        |
+--------------------------+
|2019-09-30 00:08:27.272846|
+--------------------------+

(or)

val df = Seq("2019-09-30 00:08:27.272846").toDF("dt").select(col("dt").cast("timestamp"))

//add new column to get last 3 digits from dt column

val df1 = df.withColumn("ms",expr("substring(dt,-3)")).show(false)

然后以 json 格式写入df1 to HDFS位置,当您再次读取 json 文件时,连接 dt + ms字段以重新创建您的original timestamp值。


推荐阅读