【问题标题】:spark-hive - Upsert into dynamic partition hive table throws an error - Partition spec contains non-partition columnsspark-hive - Upsert 到动态分区 hive 表中会引发错误 - 分区规范包含非分区列
【发布时间】:2018-08-06 18:46:42
【问题描述】:

我正在使用 spark 2.2.1 和 hive2.1。我正在尝试将覆盖多个分区插入现有的分区配置单元/镶木地板表中。

表是使用 sparkSession 创建的。

我有一个带有分区 P1 和 P2 的表“mytable”。

我在 sparkSession 对象上设置了以下内容:

"hive.exec.dynamic.partition"=true
"hive.exec.dynamic.partition.mode"="nonstrict"

代码:

val df = spark.read.csv(pathToNewData) df.createOrReplaceTempView("updateTable") //here 'df' may contains data from multiple partitions. i.e. multiple values for P1 and P2 in data.

spark.sql("insert overwrite table mytable PARTITION(P1, P2) select c1, c2,..cn, P1, P2 from updateTable") // I made sure that partition columns P1 and P2 are at the end of projection list.

我收到以下错误:

org.apache.spark.sql.AnalysisException: org.apache.hadoop.hive.ql.metadata.Table.ValidationFailureSemanticException: Partition spec {p1=, p2=, P1=1085, P2=164590861} contains non-partition columns;

dataframe 'df' 有 P1=1085, P2=164590861 的记录。看起来像是外壳问题(下与上)。我在查询中尝试了这两种情况,但仍然无法正常工作。

编辑:

Insert 语句适用于静态分区,但这不是我想要的: 例如以下作品

spark.sql("insert overwrite table mytable PARTITION(P1=1085, P2=164590861) select c1, c2,..cn, P1, P2 from updateTable where P1=1085 and P2=164590861")

Create table stmt:

`CREATE TABLE `my_table`(
  `c1` int, 
  `c2` int, 
  `c3` string, 
  `p1` int, 
  `p2` int)
PARTITIONED BY ( 
  `p1` int, 
  `p2` int)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  'maprfs:/mds/hive/warehouse/my.db/xc_bonus'
TBLPROPERTIES (
  'spark.sql.partitionProvider'='catalog', 
  'spark.sql.sources.schema.numPartCols'='2', 
  'spark.sql.sources.schema.numParts'='1', 
  'spark.sql.sources.schema.part.0'='{.spark struct metadata here.......}'; 
  'spark.sql.sources.schema.partCol.0'='P1', //Spark is using Capital Names for Partitions; while hive is using lowercase
  'spark.sql.sources.schema.partCol.1'='P2', 
  'transient_lastDdlTime'='1533665272')`

在上面,spark.sql.sources.schema.partCol.0 使用全部大写,而PARTITIONED BY 语句使用全部小写作为分区列

【问题讨论】:

  • 你能分享 'mytable' 的 'Create table..." 语句吗?它是作为分区表创建的吗?
  • @venBigData 在描述中添加了 create table stmt

标签: apache-spark hive parquet


【解决方案1】:

基于异常并假设表“mytable”是作为分区表创建的,其中 P1 和 P2 作为分区。克服此异常的一种方法是在执行命令之前手动强制一个虚拟分区。尝试做

spark.sql("alter table mytable add partition (p1=default, p2=default)").

一旦成功,执行您的插入覆盖语句。希望这有帮助吗?

【讨论】:

    【解决方案2】:

    正如我在 EDIT 部分中提到的问题实际上是 hive 和 spark 之间的分区列套管(下部与上部)不同!我创建了所有大写的配置单元表,但配置单元内部仍将其存储为小写,但 spark 元数据保留为我想要的大写。使用所有小写分区列修复 create 语句修复了后续更新的问题! 如果您使用的是 hive 2.1 和 spark 2.2,请确保 create 语句中的以下属性具有相同的大小写。

    PARTITIONED BY ( 
    p1int, 
    p2int)
    'spark.sql.sources.schema.partCol.0'='p1', 
      'spark.sql.sources.schema.partCol.1'='p2',
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-21
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多