【问题标题】:Error while inserting into partitioned hive table for spark scala为 spark scala 插入分区配置单元表时出错
【发布时间】:2021-10-30 20:11:04
【问题描述】:

我的配置单元表具有以下结构

创建表 gcganamrswp_work.historical_trend_result( 列名字符串,
metric_name 字符串,
current_percentage 字符串,
lower_threshold 双倍,
双倍上限,
calc_status 字符串,
final_status 字符串,
support_override 字符串,
数据集名称字符串,
插入时间戳字符串,
appid 字符串,
当前日期字符串,
指标图)
由 (
应用名称字符串,
year_month int)
存储为镶木地板 TBLPROPERTIES ("parquet.compression"="SNAPPY");

我有带有架构的 spark 数据框

root
 |-- metric_name: string (nullable = true)
 |-- column_name: string (nullable = true)
 |-- Lower_Threshold: double (nullable = true)
 |-- Upper_Threshold: double (nullable = true)
 |-- Current_Percentage: double (nullable = true)
 |-- Calc_Status: string (nullable = false)
 |-- Final_Status: string (nullable = false)
 |-- support_override: string (nullable = false)
 |-- Dataset_Name: string (nullable = false)
 |-- insert_timestamp: string (nullable = false)
 |-- appId: string (nullable = false)
 |-- currentDate: string (nullable = false)
 |-- indicator: map (nullable = false)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = false)
 |-- appname: string (nullable = false)
 |-- year_month: string (nullable = false)

当我尝试使用以下代码插入配置单元表时失败

    spark.conf.set("hive.exec.dynamic.partition", "true")
    spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")
    data_df.repartition(1)
      .write.mode("append")
      .format("hive")
      .insertInto(Outputhive_table)

Spark 版本:Spark 2.4.0

错误:

ERROR Hive:1987 - 使用参数加载分区时出现异常 partPath=hdfs://gcgprod/data/work/hive/historical_trend_result/.hive-staging_hive_2021-09-01_04-34-04_254_8783620706620422928-1/-ext-10000/_temporary/0, table=historical_trend_result, partSpec={appname=, year_month=}, 替换=假,listBucketingEnabled=假,isAcid=假, hasFollowingStatsTask=false org.apache.hadoop.hive.ql.metadata.HiveException: MetaException(消息:分区规范不正确。{appname=, 年月=})在 org.apache.hadoop.hive.ql.metadata.Hive.loadPartitionInternal(Hive.java:1662) 在 org.apache.hadoop.hive.ql.metadata.Hive.lambda$loadDynamicPartitions$4(Hive.java:1970) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:748) 引起: MetaException(消息:分区规范不正确。{appname=, 年月=})在 org.apache.hadoop.hive.metastore.Warehouse.makePartName(Warehouse.java:329) 在 org.apache.hadoop.hive.metastore.Warehouse.makePartPath(Warehouse.java:312) 在 org.apache.hadoop.hive.ql.metadata.Hive.genPartPathFromTable(Hive.java:1751) 在 org.apache.hadoop.hive.ql.metadata.Hive.loadPartitionInternal(Hive.java:1607)

我已经在数据框的最后一列中指定了分区列,所以我希望它将最后两列视为分区列。我想使用相同的例程来插入不同的表,所以我不想明确提及分区列

【问题讨论】:

  • 可能是因为您的架构显示 year_mont int,但数据框显示的是 year_month 字符串?

标签: scala apache-spark hive


【解决方案1】:

我认为问题在于某些记录将appnameyear_month 作为字符串。至少这是由

建议的
Partition spec is incorrect. {appname=, year_month=}

确保分区列永远不为空或为空!另请注意,DataFrame 和您的架构(字符串/整数)之间的 year_month 类型不一致

【讨论】:

  • 我检查了分区列不为空或为空。另外,我将 year_month 的数据类型更改为 int。但仍然得到同样的错误。请帮忙
【解决方案2】:

只是回顾一下您正在使用 spark 将数据写入具有动态分区的配置单元表。所以我下面的回答是基于相同的,如果我的理解不正确,请随时在评论中纠正我。

虽然您有一个动态分区的表(按 app_name 和 year_month),但 spark 作业不知道目标中的分区字段,因此您仍然需要告诉您的 spark 作业目标表的分区字段.

这样的东西应该可以工作

data_df.repartition(1)
      .write
      .partitionBy("appname", "year_month")
      .mode(SaveMode.Append)
      .saveAsTable(Outputhive_table)

确保通过执行类似的操作启用对动态分区的支持

hiveContext.setConf("hive.exec.dynamic.partition", "true")
hiveContext.setConf("hive.exec.dynamic.partition.mode", "nonstrict")

查看 Itai Yaffe 的这篇文章,这可能很方便https://medium.com/nmc-techblog/spark-dynamic-partition-inserts-part-1-5b66a145974f

【讨论】:

  • 我试过这段代码。我收到错误消息 - partitionBy() can't be used together with DataFrameWriter.insertInto
  • 你运行的 spark 版本是什么?
  • @Arvinth,我已经修改了旧版本 spark 的答案,这应该可以工作
  • 尝试更新代码后出现错误:org.apache.spark.sql.AnalysisException: partition column appname,year_month is not defined in table gcganamrswp_work.historical_trend_result, defined table columns are: column_name, metric_name, current_percentage, lower_threshold, upper_threshold, calc_status, final_status, support_override, dataset_name, insert_timestamp, appid, currentdate, indicator, appname, year_month;
  • @arvinth 你写错了表。根据您上面的问题,变量 Outputhive_table 应设置为 gcgcrsnapsd_equifax_t_db.historical_trend_result 而从错误消息中它似乎设置为 gcganamrswp_work.historical_trend_result
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
相关资源
最近更新 更多