ORC 文件上的 Spark SQL 没有 return 正确的架构(列名)

Spark SQL on ORC files doesn't return correct Schema (Column names)

我有一个包含 ORC 文件的目录。我正在使用以下代码创建 DataFrame

var data = sqlContext.sql("SELECT * FROM orc.`/directory/containing/orc/files`");

它 returns 具有此架构的数据框

[_col0: int, _col1: bigint]

预期的模式是

[scan_nbr: int, visit_nbr: bigint]

当我查询镶木地板格式的文件时,我得到了正确的架构。

我是否缺少任何配置?

添加更多详细信息

这是 Hortonworks Distribution HDP 2.4.2(Spark 1.6.1、Hadoop 2.7.1、Hive 1.2.1)

我们没有更改 HDP 的默认配置,但这绝对不同于 Hadoop 的普通版本。

数据由上游 Hive 作业写入,一个简单的 CTAS(CREATE TABLE sample STORED AS ORC as SELECT ...)。

我在 CTAS 使用最新的 2.0.0 配置单元生成的文件上对此进行了测试,它保留了 orc 文件中的列名。

问题出在Hive版本,1.2.1,有这个bugHIVE-4243

这已在 2.0.0 中修复。

如果你也有 parquet 版本,你可以只复制列名,这就是我所做的(另外,日期列是 orc 的分区键所以不得不将它移到最后):

tx = sqlContext.table("tx_parquet")
df = sqlContext.table("tx_orc")
tx_cols = tx.schema.names
tx_cols.remove('started_at_date')
tx_cols.append('started_at_date') #move it to end
#fix column names for orc
oldColumns = df.schema.names
newColumns = tx_cols
df = functools.reduce(
    lambda df, idx: df.withColumnRenamed(
        oldColumns[idx], newColumns[idx]), range(
            len(oldColumns)), df)

如果版本升级不可用,快速修复可能是使用 PIG 重写 ORC 文件。这似乎工作得很好。

我们可以使用:

val df = hiveContext.read.table("tableName")

您的 df.schemadf.columns 将给出实际的列名。

设置

sqlContext.setConf('spark.sql.hive.convertMetastoreOrc', 'false')

解决了这个问题。