我正在使用spark 2.2.1和hive2.1。我正在尝试将覆盖多个分区插入到现有的分区配置单元/Parquet地板表中。
表是使用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(
c1int,
c2int,
c3string,
p1int,
p2int) PARTITIONED BY (
p1int,
p2int) 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` 使用全大写while `PARTITIONED BY` 语句对分区列使用所有小写字母
2条答案
按热度按时间vaj7vani1#
基于该异常,并假设表“mytable”是以p1和p2为分区创建的分区表。克服此异常的一种方法是在执行命令之前手动强制虚拟分区。试着做
sql(“alter table mytable add partition(p1=default,p2=default)”)。
一旦成功,执行insert overwrite语句。希望这有帮助?
jjhzyzn02#
正如我在编辑部分提到的,这个问题实际上是由于hive和spark之间的分区列大小写(下部和上部)的不同!我创建了包含所有大写字母的配置单元表,但配置单元仍然在内部将其存储为小写字母,但spark元数据保留为我所希望的大写字母。修复所有小写分区列的create语句修复了后续更新的问题!如果您使用的是hive2.1和spark2.2,请确保create语句中的以下属性具有相同的大小写。