我遇到一个问题,我无法查看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")
这时,我们可以看到来自蜂巢的所有数据。然后,我们将使用新列
创建另一个数据框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可以完美地显示各列(因此,其中的数据使配置单元难以读取此列)。谁能建议解决此问题的方法?
答案 0 :(得分:1)
由于在蜂巢中尚未创建分区,因此您可以在第一次尝试的年龄列中查看数据,因此蜂巢使用了当前可用的包含年龄列的架构。
第二次尝试时,您正在写入配置单元的现有分区,因此配置单元将对创建分区后添加的所有列应用空值。
如果将新数据写入任何新分区,则将立即看到数据。
如果删除分区然后写入与缓存相同的数据帧,则配置单元在查询时也会显示地址。
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