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

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


地板数据文件存储在/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中的表格上选择时,它不会显示任何结果。

我试过了:


运行msck命令,例如:

msck repair table dimcompany;

设置以下内容:

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



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

最佳答案

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

由于Hive将其列名转换为小写,因此您的分区列存储为setid而不是SetId。因此,当Hive在区分大小写的数据存储区中搜索分区/文件夹时,它将查找setid=some_value却什么也找不到,因为您的数据文件夹的格式为SetId=some_value

为此,请将SetId转换为小写或snake_case。您可以通过对DataFrame中的列进行别名来使用它:

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


您可能还必须基于此StackOverflow post在执行create语句之前设置这些属性。

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


创建表后,还尝试运行

msck repair table <your_schema.your_table>;

09-26 18:32