【问题标题】:Spark SQL saveAsTable is not compatible with Hive when partition is specified指定分区时,Spark SQL saveAsTable 与 Hive 不兼容
【发布时间】:2017-01-07 11:01:18
【问题描述】:

一种边缘情况,在使用分区的 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");

火花警告:

将分区数据源关系持久化到 Hive 元存储中 Spark SQL 特定格式,与 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 兼容?

【问题讨论】:

  • 数据存入hdfs,元数据存入hive metastore
  • 您是否尝试“注册为临时表”然后运行 ​​SQL 命令“CREATE TABLE”然后“INSERT ”?
  • 谢谢 Samson,还没有,但 saveAsTable 不是在做它应该做的吗?
  • 可能取决于您使用的 Spark 版本,例如“它不是错误,它是一个特性” vs. “总有一天会实现”

标签: hive apache-spark-sql partitioning parquet


【解决方案1】:

这是因为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")

【讨论】:

  • 嗨,欢迎来到 StackOverflow,感谢您的回答。由于链接会随着时间而变化,您能否编辑您的答案以在此处引用解决方案的相关部分?谢谢!
【解决方案2】:

一种解决方案是使用 Hive 创建表,然后使用 ...partitionBy("year").insertInto("default.mytable") 保存数据。

根据我的经验,在 Hive 中创建表然后使用 ...partitionBy("year").saveAsTable("default.mytable") 不起作用。这是 Spark 1.6.2 的版本。

【讨论】:

  • 我认为这不适用于 spark 2.0.0,我得到 User class threw exception: org.apache.spark.sql.AnalysisException: insertInto() can't be used together with partitionBy(). Partition columns have already be defined for the table. It is not necessary to use partitionBy().;
猜你喜欢
  • 2019-12-10
  • 2016-02-20
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 2016-12-13
相关资源
最近更新 更多