某种边缘情况,当在带有分区的Spark SQL中保存 Parquet 表时,

#schema definitioin
final StructType schema = DataTypes.createStructType(Arrays.asList(
    DataTypes.createStructField("time", DataTypes.StringType, true),
    DataTypes.createStructField("accountId", DataTypes.StringType, true),
    ...

DataFrame df = hiveContext.read().schema(schema).json(stringJavaRDD);

df.coalesce(1)
    .write()
    .mode(SaveMode.Append)
    .format("parquet")
    .partitionBy("year")
    .saveAsTable("tblclick8partitioned");

Spark警告:



在Hive中:
hive> describe tblclick8partitioned;
OK
col                     array<string>           from deserializer
Time taken: 0.04 seconds, Fetched: 1 row(s)

显然,该架构是不正确的-但是,如果我在Spark SQL中使用saveAsTable而不进行分区,则可以毫无问题地查询该表。

问题是如何在Spark SQL中使 Parquet 表与具有分区信息的Hive兼容?

最佳答案

那是因为DataFrame.saveAsTable创建RDD分区而不是Hive分区,所以解决方法是在调用DataFrame.saveAsTable之前通过hql创建表。 SPARK-14927的示例如下所示:

hc.sql("create external table tmp.partitiontest1(val string) partitioned by (year int)")

Seq(2012 -> "a", 2013 -> "b", 2014 -> "c").toDF("year", "val")
  .write
  .partitionBy("year")
  .mode(SaveMode.Append)
  .saveAsTable("tmp.partitiontest1")

10-08 09:35