首页 文章

spark-hive - Upsert into动态分区hive表会引发错误 - 分区规范包含非分区列

提问于
浏览
0

我正在使用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的记录 . 看起来像套管问题(较低与较高) . 我在我的查询中尝试了两种情况,但它仍然无法正常工作 .

EDIT:

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")

创建表格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 语句使用全部小写的分区列

2 回答

  • 0

    基于Exception并假设表'mytable'是作为分区表创建的,P1和P2作为分区 . 克服此异常的一种方法是在执行命令之前手动强制虚拟分区 . 试着做

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

    成功后,执行insert overwrite语句 . 希望这可以帮助?

  • 0

    正如我在编辑部分提到的那样,问题实际上与蜂巢和火花之间的分区列套管(下部和上部)不同!我创建了包含所有Upper案例的hive表,但是hive仍然在内部存储它作为小写但保留的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',
    

相关问题