在存储在 hdfs 中的 orc 文件上创建外部表后,select * 返回时间戳的空值

Posted

技术标签:

【中文标题】在存储在 hdfs 中的 orc 文件上创建外部表后,select * 返回时间戳的空值【英文标题】:select * returns null values for timestamp after creating external table on orc files stored in hdfs 【发布时间】:2019-09-09 18:07:48 【问题描述】:

我正在存储在 hdfs 中的 orc 文件之上创建一个外部表。我在数据文件中有 process_timestamp 列和时间戳

创建表后,我执行MSCK REPAIR TABLE <TABLE-NAME>。但是,查询表时间戳列时返回空值而不是实际时间戳

from datetime import date
from pyspark.sql.functions import lit, to_date, from_unixtime, unix_timestamp
from pyspark.sql import SparkSession
spark = SparkSession.builder \
        .appName("test_conn") \
        .getOrCreate()

df = spark.createDataFrame([('Alice', 1)])

timestamp = today.strftime("%Y-%m-%d %H:%M:%S")

df = df.withColumn('process_timestamp', unix_timestamp(lit(timestamp), 'yyyy-MM-dd HH:mm:ss').cast('timestamp'))

process_timestamp 在 orc 文件中看起来像这样 '2019-09-09 00:00:00'

Schema 看起来也不错:

--process_timestamp: timestamp (nullable = true)

但是在查询时,会返回空值process_timestamp - NULL

我尝试如下设置 serde 属性,但没有用。

ALTER TABLE <table_name> SET SERDEPROPERTIES ("timestamp.formats"="yyyy-MM-dd'T'HH:mm:ss"); 

请帮我解决这个问题。查询时如何从外部表返回实际时间戳值?任何帮助将不胜感激。

【问题讨论】:

您可以使用 ORC 工具查看 ORC 文件。 orc.apache.org/docs/java-tools.html 它将帮助您确定问题是在数据中还是在元数据中。您还可以将该字段添加为字符串并查看返回的内容。时间戳类型更敏感。 【参考方案1】:

我通过将文件直接保存在 hdfs 位置作为 ORC 并在数据之上创建外部表来解决此问题。问题在于将文件保存到 hdfs 位置。

df.coalesce(1).write.format('orc').mode('append').partitionBy('process_date').save(path)

在上面的语句中,我添加了 partitionBy() 并在外部表上做了一个 MSCK,它就像一个魅力。

【讨论】:

以上是关于在存储在 hdfs 中的 orc 文件上创建外部表后,select * 返回时间戳的空值的主要内容,如果未能解决你的问题,请参考以下文章

Hive Streaming 追加 ORC 文件

parquet和orc

从 orc 文件创建配置单元表而不指定架构

带有 partitionBy 的 Spark DataFrame saveAsTable 在 HDFS 中不创建 ORC 文件

hive外部表分区

Hive:无法为 HDFS 中的现有数据创建外部表