Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 试图覆盖配置单元分区时,写入到_配置单元u默认分区_u;的损坏行_Apache Spark_Hive_Apache Spark Sql - Fatal编程技术网

Apache spark 试图覆盖配置单元分区时,写入到_配置单元u默认分区_u;的损坏行

Apache spark 试图覆盖配置单元分区时,写入到_配置单元u默认分区_u;的损坏行,apache-spark,hive,apache-spark-sql,Apache Spark,Hive,Apache Spark Sql,我在尝试使用Spark 2.3覆盖配置单元表中的分区时看到一些非常奇怪的行为 首先,我在构建SparkSession时设置以下设置: .config("spark.sql.sources.partitionOverwriteMode", "dynamic") 然后,我将一些数据复制到新表中,并按date\u id列进行分区 ds .write .format("parquet") .option("compression", "snappy") .option("auto.pu

我在尝试使用Spark 2.3覆盖配置单元表中的分区时看到一些非常奇怪的行为

首先,我在构建SparkSession时设置以下设置:

.config("spark.sql.sources.partitionOverwriteMode", "dynamic")
然后,我将一些数据复制到新表中,并按date\u id列进行分区

ds
  .write
  .format("parquet")
  .option("compression", "snappy")
  .option("auto.purge", "true")
  .mode(saveMode)
  .partitionBy("date_id")
  .saveAsTable("tbl_copy")
我可以在HDFS中看到相关的日期id目录已经创建

然后,我创建一个数据集,其中包含要覆盖的分区的数据,该分区包含单个日期id的数据,并插入到配置单元中,如下所示:

  ds
    .write
    .mode(SaveMode.Overwrite)
    .insertInto("tbl_copy")
作为健全性检查,我将相同的数据集写入一个新表

      ds
        .write
        .format("parquet")
        .option("compression", "snappy")
        .option("auto.purge", "true")
        .mode(SaveMode.Overwrite)
        .saveAsTable("tmp_tbl")
tmp_tbl中的数据与预期完全一致

然而,当我查看tbl_copy时,我看到一个新的HDFS目录'date_id=HIVE_DEFAULT_分区

查询tbl_cpy

SELECT * from tbl_copy WHERE date_id IS NULL
我看到了应该插入到分区date_id=20180523中的行,但是date_id列为null,一个不相关的row_changed列已经填充了值20180523

似乎是由于插入到配置单元中导致我的数据被破坏了。将相同的数据集写入新表不会导致任何问题


有人能解释一下吗?

因此分区列必须是数据集中的最后一列

我通过在Dataset[T]上使用以下方法解决了这个问题

def partitionsTail(partitionColumns: Seq[String]) = {
  val columns = dataset.schema.collect{ case s if !partitionColumns.contains(s.name) => s.name} ++ partitionColumns

  dataset.select(columns.head, columns.tail: _*).as[T]
} 

因此,分区列似乎必须是数据集中的最后一列

我通过在Dataset[T]上使用以下方法解决了这个问题

def partitionsTail(partitionColumns: Seq[String]) = {
  val columns = dataset.schema.collect{ case s if !partitionColumns.contains(s.name) => s.name} ++ partitionColumns

  dataset.select(columns.head, columns.tail: _*).as[T]
} 

是的,这是一个棘手的行为,请在文档中解释:

与saveAsTable不同,insertInto忽略列名,只使用 基于位置的分辨率。例如:


是的,这是一个棘手的行为,请在文档中解释:

与saveAsTable不同,insertInto忽略列名,只使用 基于位置的分辨率。例如:


是否有架构更改?数据集的架构完全相同,并且数据集正在正确写入新表中。我在过去看到过两个数据集的联合问题,其中问题是由于列的顺序而出现的。我已将正在写入的数据集中的列重新排序为与正在被覆盖的表相同,但问题仍然存在。是否有架构更改?数据集的架构完全相同,并且数据集正在正确写入新表中。我在过去看到过两个数据集的联合问题,其中问题是由于列的顺序而出现的。我已经对正在写入的数据集中的列进行了重新排序,使其与正在被覆盖的表相同,但问题仍然存在。您能详细说明一下吗?不知道为什么会这样。你能详细说明一下吗?不确定为什么会这样。