【问题标题】:Cannot view new data created via Spark SQL无法查看通过 Spark SQL 创建的新数据
【发布时间】:2020-04-13 04:22:57
【问题描述】:

我面临一个问题,我无法查看 Hive 中的某些数据。重现问题的步骤。创建表

drop table if exists hive_parquet_nulls_test ;

create table hive_parquet_nulls_test (
name String
)
 partitioned by (report_date DATE)
 stored as PARQUET;

然后创建一个数据框和一个新列并加载它们

import java.sql.Date
import org.apache.spark.sql._
import org.apache.spark.sql.functions._



case class Person(name : String, age : Int, report_date : Date)

val df = sc.parallelize(
    Seq(Person("Steve", 30, Date.valueOf("2016-09-30")), 
        Person("James", 29, Date.valueOf("2016-09-30")))).toDF

df.show(false)

spark.sql(s"ALTER TABLE hive_parquet_nulls_test  ADD COLUMNS (age integer)");
spark.sql(s"REFRESH TABLE hive_parquet_nulls_test");

df.write.mode(SaveMode.Overwrite).insertInto("hive_parquet_nulls_test")

此时,我们可以看到来自 hive 的所有数据。然后我们将创建另一个带有新列的数据框

val df = spark.table("hive_parquet_nulls_test")

val newDF = df.withColumn("address", lit("123 Green Avenue, London"))

newDF.show(false)


spark.sql(s"ALTER TABLE hive_parquet_nulls_test  ADD COLUMNS (address string)")
spark.sql(s"REFRESH TABLE hive_parquet_nulls_test")

spark.sql(s"describe hive_parquet_nulls_test")

val finalFieldNames = newDF.schema.fieldNames

val finalPartitionedDF = newDF.select($"name", $"age", $"address", $"report_date")
      .cache()

finalPartitionedDF.write.mode(SaveMode.Overwrite).insertInto("hive_parquet_nulls_test_test")


spark.table("hive_parquet_nulls_test").show(false)

加载后,只有地址列显示为空。这只发生在蜂巢中。 Spark 完美地显示了这些列(所以那里的数据,hive 正在努力阅读这个列)。谁能建议如何解决这个问题?

【问题讨论】:

  • Show create table in hive 是否显示添加的新列?你能检查一下hive中ddl的updatetimestamp吗,你也可以试试msck修复表。最后验证 spark 引用的 hive/hive-site.xml 是否与您使用的 hive shell 相同
  • 您在 hive_parquet_nulls_test 表中添加了地址列,但将数据帧写入 hive_parquet_nulls_test_test
  • @KSNidhin,是的 show create 正在显示添加的新列,并且时间戳也已更新。我什至添加了一个 load_timestamp 列并检查了时间戳是在表更新之后。 (数据在那里并且presto和spark并显示数据,但Hive无法读取它)还尝试了msck修复表。关于spark是否使用相同的hive-site.xml,没有。我正在使用 emr(spark 和 hive 有自己的 hive-site.xml)。您能否指出我可以覆盖火花设置以使用 hive 的 hive-site.xml 的任何文档。谢谢
  • @RamdevSharma - 很抱歉这是一个错误。

标签: java apache-spark hive apache-spark-sql


【解决方案1】:

您可以在第一次尝试中看到年龄列的数据,因为尚未在 hive 中创建分区,因此 hive 使用了当前可用的架构,其中包括年龄列。

第二次尝试时,您正在写入 hive 的现有分区,因此 hive 正在为创建分区后添加的所有列应用空值。

如果您将新数据写入任何新分区,那么您将立即看到数据。

如果你删除分区,然后写入你缓存的相同数据帧,那么 hive 在查询时也会显示地址。

spark.sql("alter table hive_parquet_nulls_test drop partition(report_date='2016-09-30')");
finalPartitionedDF.write.mode(SaveMode.Overwrite).insertInto("hive_parquet_nulls_test")

在蜂巢壳上:

select address from hive_parquet_nulls_test;
OK
123 Green Avenue, London
123 Green Avenue, London

这似乎是由于 hive 错误https://issues.apache.org/jira/browse/HIVE-6131

【讨论】:

    猜你喜欢
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多