gpt4 book ai didi

hadoop - 如何使用配置单元 1.2 从 s3 中的 Parquet 文件创建外部表?

转载 作者:可可西里 更新时间:2023-11-01 14:55:24 24 4
gpt4 key购买 nike

我在 Qubole(Hive) 中创建了一个外部表,它从 s3 读取 parquet(compressed: snappy) 文件,但是在执行 SELECT * table_name 时,我得到了所有的空值除分区列之外的列

我尝试在 SERDEPROPERTIES 中使用不同的 serialization.format 值,但我仍然面临同样的问题。在删除属性 'serialization.format' = '1' 时,我得到了 ERROR: Failed with exception java.io.IOException:Can not read value at 0 in block -1 in file s3://path_to_parquet/.

我检查了 parquet 文件并能够使用 parquet-tools 读取数据:

**file_01.snappy.parquet:**
{"col_2":1234,"col_3":ABC}
{"col_2":124,"col_3":FHK}
{"col_2":12515,"col_3":UPO}


**External table stmt:**
CREATE EXTERNAL TABLE parquet_test
(
col2 int,
col3 string
)
PARTITIONED BY (col1 date)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
)
STORED AS PARQUET
LOCATION 's3://path_to_parquet'
TBLPROPERTIES ('parquet.compress'='SNAPPY');

Result:
col_1 col_2 col_3
5/3/19 NULL NULL
5/4/19 NULL NULL
5/5/19 NULL NULL
5/6/19 NULL NULL

Expected Result:
col_1 col_2 col_3
5/3/19 1234 ABC
5/4/19 124 FHK
5/5/19 12515 UPO
5/6/19 1234 ABC

最佳答案

假设该表是使用 Hive 创建并使用 Spark 读取的,编写以下答案(因为问题标记为 apache-spark-sql )

数据是如何创建的?

Spark 支持区分大小写的模式。当我们使用数据框 API 时,可以使用区分大小写的模式来编写。
示例:

scala> case class Employee(iD: Int, NaMe: String )
defined class Employee
scala> val df =spark.range(10).map(x => Employee(x.toInt, s"name$x")).write.save("file:///tmp/data/")
scala> spark.read.parquet("file:///tmp/data/").printSchema
root
|-- iD: integer (nullable = true)
|-- NaMe: string (nullable = true)

请注意,在上面的示例中,区分大小写得到了保留。
当我们在从 Spark 创建的数据之上创建一个 Hive 表时,Hive 将能够正确读取它,因为它不区分大小写。
而当使用 Spark 读取相同的数据时,它使用 Hive 的模式,默认情况下是小写的,返回的行是 null .
为了克服这个问题,Spark 引入了一个配置 spark.sql.hive.caseSensitiveInferenceMode .

object HiveCaseSensitiveInferenceMode extends Enumeration {
val INFER_AND_SAVE, INFER_ONLY, NEVER_INFER = Value
}

val HIVE_CASE_SENSITIVE_INFERENCE = buildConf("spark.sql.hive.caseSensitiveInferenceMode")
.doc("Sets the action to take when a case-sensitive schema cannot be read from a Hive " +
"table's properties. Although Spark SQL itself is not case-sensitive, Hive compatible file " +
"formats such as Parquet are. Spark SQL must use a case-preserving schema when querying " +
"any table backed by files containing case-sensitive field names or queries may not return " +
"accurate results. Valid options include INFER_AND_SAVE (the default mode-- infer the " +
"case-sensitive schema from the underlying data files and write it back to the table " +
"properties), INFER_ONLY (infer the schema but don't attempt to write it to the table " +
"properties) and NEVER_INFER (fallback to using the case-insensitive metastore schema " +
"instead of inferring).")
.stringConf
.transform(_.toUpperCase(Locale.ROOT))
.checkValues(HiveCaseSensitiveInferenceMode.values.map(_.toString))
.createWithDefault(HiveCaseSensitiveInferenceMode.INFER_AND_SAVE.toString)

INFER_AND_SAVE - Spark 推断模式并存储在 Metastore 中作为表的一部分 TBLEPROPERTIES (desc extended <table name> 应该揭示这一点)
如果属性的值NOT或者INFER_AND_SAVEINFER_ONLY ,然后 Spark 使用 Metastore 表中的模式,并且将无法读取 parquet 文件。该属性的默认值为 INFER_AND_SAVE从 Spark 2.2.0 开始。

我们可以检查以下内容,看看问题是否与架构敏感性有关:
1. spark.sql.hive.caseSensitiveInferenceMode 的值(spark.sql("set spark.sql.hive.caseSensitiveInferenceMode") 应该揭示这一点)
2.如果使用Spark创建的数据
3.如果2为真,检查Schema是否区分大小写(spark.read(<location>).printSchema)4. 如果 3 使用区分大小写的架构并且 1 的输出不是 INFER_AND_SAVE/INFER_ONLY , 设置 spark.sql("set spark.sql.hive.caseSensitiveInferenceMode=INFER_AND_SAVE") ,删除表,重新创建表并尝试从 Spark 读取数据。

关于hadoop - 如何使用配置单元 1.2 从 s3 中的 Parquet 文件创建外部表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56157058/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com