Spark SQL 到 Hive 表 - 日期时间字段小时错误
Posted
技术标签:
【中文标题】Spark SQL 到 Hive 表 - 日期时间字段小时错误【英文标题】:Spark SQL to Hive table - Datetime Field Hours Bug 【发布时间】:2017-11-22 11:29:10 【问题描述】:我遇到了这个问题:当我使用 spark.sql 在 Hive 中输入时间戳字段时 数据,时间奇怪地变成了21:00:00!
让我解释一下:
我有一个用 spark.sql 读取的 csv 文件。我读取文件,将其转换为数据框并将其存储在 Hive 表中。此文件中的字段之一是日期,格式为“2017 年 3 月 10 日”。我要输入的 Hive 中的字段是 Timestamp 格式(我使用这种数据类型而不是 Date 的原因是我想用 Impala 查询表,而 Impala 只有 Timestamp data type,所以它不是一种简单地将数据类型更改为日期的解决方案)
正如您从文档中看到的那样,Hive Timestamp 数据类型具有“YYYY-MM-DD HH:MM:SS”格式,因此在我将数据框输入到 Hive 表之前,我将日期值转换为适当的格式。
这是我的 Python 代码:
from datetime import datetime
from pyspark.sql.functions import udf
df = spark.read.csv("hdfs:/user/../MyFile.csv", header=True)
#Use a user defined function to convert date format
def DateConvert(x):
x_augm = str(x)+" 00:00:00"
datetime_object = datetime.strptime(x_augm,'%d/%m/%Y %H:%M:%S')
return datetime_object.strftime('%Y-%m-%d %H:%M:%S')
DateConvert_udf = udf(DateConvert)
df= df.withColumn("Trans_Date", DateConvert_udf("Trans_Date"))
这会正确格式化时间戳。当我跑步时
df.select("Trans_Date").show(10, False)
我明白了:
+-------------------+ |Trans_Date | +-------------------+ |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| |2017-10-16 00:00:00| +-------------------+
然后我像这样使用 Spark SQL 将数据导入 Hive
df.createOrReplaceTempView('tempTable')
spark.sql("insert into table db.table select * from tempTable")
我的问题是,当我转到 Hive 时,我的 Timestamp 字段的值如下:
2017-10-16 21:00:00
这很奇特!
提前感谢您的任何建议
【问题讨论】:
【参考方案1】:这是将数据保存到具有 TIMESTAMP 数据类型的 Hive 表中时的常见问题。
当您将数据保存到 Hive 表中时,TIMESTAMP 值表示写入数据的主机的本地时区。
这里 2017-10-16 00:00:00 - UTC(默认)转换为 2017-10-16 21:00:00 - Hive 主机的本地时区。
为避免因意外时区问题而导致不希望的结果,在 Impala 中,时间戳在写入数据文件或从数据文件读取时都相对于 UTC 进行存储和解释。
您可以参考以下文档了解必要的配置设置。 https://www.cloudera.com/documentation/enterprise/5-9-x/topics/impala_timestamp.html#timestamp
【讨论】:
很好的解释,但哪种是避免它的正确方法?我发现添加像 00:00:00.0 这样的毫秒可以解决问题,我会进行编辑以包含它,但是还有其他方法吗? 我不认为添加毫秒可以解决问题。你试过了吗?【参考方案2】:通过在 Spark 中创建时间戳时添加浮点数字,我能够解决这个问题。我只是将小时格式化为 HH:MM:SS.ff 格式,现在 Hive 表中的时间显示为 00:00:00,这正是我想要的。
我的新日期转换例程是:
def DateConvert(x):
x_augm = str(x)+" 00:00:00.0"
datetime_object = datetime.strptime(x_augm,'%d/%m/%Y %H:%M:%S.%f')
return datetime_object.strftime('%Y-%m-%d %H:%M:%S.%f')
【讨论】:
以上是关于Spark SQL 到 Hive 表 - 日期时间字段小时错误的主要内容,如果未能解决你的问题,请参考以下文章
在 Spark SQL 中找不到 Hive 表 - Cloudera VM 中的 spark.sql.AnalysisException
Spark 2.3.0 SQL 无法将数据插入 hive hbase 表