簡體   English   中英

spark-hive-向動態分區配置單元表中更新會引發錯誤-分區規范包含非分區列

[英]spark-hive - Upsert into dynamic partition hive table throws an error - Partition spec contains non-partition columns

我正在使用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. ie 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;

數據幀'df'具有記錄P1 = 1085,P2 = 164590861。 看起來像是套管問題(下部與上部)。 我在查詢中嘗試了兩種情況,但仍然無法正常工作。

編輯:

插入語句可用於靜態分區,但這不是我想要的:例如,以下方法

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 ( 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') 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”創建為以P1和P2為分區的分區表。 克服此異常的一種方法是在執行命令之前手動強制使用虛擬分區。 嘗試做

spark.sql(“更改表mytable添加分區(p1 =默認,p2 =默認)”)。

成功后,執行插入覆蓋語句。 希望這可以幫助?

正如我在EDIT部分中提到的那樣,問題實際上是蜂巢和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',

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM