首页 > 解决方案 > Hive 外部表无法查看分区 Parquet 文件

问题描述

我正在setid使用 Spark 生成 Parquet 文件(按 Snappy 压缩分区)并将它们存储在 HDFS 位置。

df.coalesce(1).write.partitionBy("SetId").
  mode(SaveMode.Overwrite).
  format("parquet").
  option("header","true").
  save(args(1))

Parquet 数据文件存储在/some-hdfs-path/testsp

然后我为它创建 Hive 表,如下所示:

CREATE EXTERNAL TABLE DimCompany(
  CompanyCode string,
  CompanyShortName string,
  CompanyDescription string,
  BusinessDate string,
  PeriodTypeInd string,
  IrisDuplicateFlag int,
  GenTimestamp timestamp
) partitioned by (SetId int)
STORED AS PARQUET LOCATION '/some-hdfs-path/testsp'
TBLPROPERTIES ('skip.header.line.count'='1','parquet.compress'='snappy');

但是,当我在 Hive 中的 table 上选择时,它没有显示任何结果。

我试过了:

  1. 运行msck命令如:

    msck repair table dimcompany;
    
  2. 设置以下内容:

    spark.sql("SET spark.sql.hive.convertMetastoreParquet=false")
    

这些都不起作用,我该如何解决?

标签: apache-sparkhivepartitioningparquet

解决方案


问题是您的分区列SetId, 使用大写字母。

由于 Hive 将其列名转换为小写,因此您的分区列存储为setid而不是SetId. 因此,当 Hive 在区分大小写的数据存储中搜索分区/文件夹时,它会查找setid=some_value并找不到任何内容,因为您的数据文件夹的格式为SetId=some_value.

要完成这项工作,请转换SetId为小写或蛇形大小写。您可以通过为 DataFrame 中的列起别名来使用它:

df.select(
... {{ your other_columns }} ...,
col("SetId").alias("set_id")
)

根据此StackOverflow 帖子,您可能还必须在执行 create 语句之前设置这些属性

SET hive.mapred.supports.subdirectories=TRUE;
SET mapred.input.dir.recursive=TRUE;

创建表后,也尝试运行

msck repair table <your_schema.your_table>;

推荐阅读