Spark 版本:Amazon EMR 5.24.0 上的 2.4.2
我有一个由 S3 Parquet 目录支持的 Glue Catalog 表。 Parquet 文件具有区分大小写的列名称(例如 lastModified
)。无论我做什么,当使用 Spark 读取 Glue Catalog 表时,我都会得到小写的列名称 (lastmodified
):
for {
i <- Seq(false, true)
j <- Seq("NEVER_INFER", "INFER_AND_SAVE", "INFER_ONLY")
k <- Seq(false, true)
} {
val spark = SparkSession.builder()
.config("spark.sql.hive.convertMetastoreParquet", i)
.config("spark.sql.hive.caseSensitiveInferenceMode", j)
.config("spark.sql.parquet.mergeSchema", k)
.enableHiveSupport()
.getOrCreate()
import spark.sql
val df = sql("""SELECT * FROM ecs_db.test_small""")
df.columns.foreach(println)
}
[1] https://medium.com/@an_chee/why-using-mixed-case-field-names-in-hive-spark-sql-is-a-bad-idea-95da8b6ec1e0
[2]https://spark.apache.org/docs/latest/sql-data-sources-parquet.html
最佳答案
编辑
以下解决方案不正确。
- Glue Crawler 不应设置
spark.sql.sources.schema.*
属性,但 Spark SQL 应该如此。 Spark 2.4 中的默认值是spark.sql.hive.caseSensitiveInferenceMode
是INFER_AND_SAVE
这意味着 Spark 从底层文件推断架构并更改表以添加spark.sql.sources.schema.*
属性为SERDEPROPERTIES
。在我们的例子中,Spark 未能这样做,因为IllegalArgumentException: Can not create a Path from an empty string
由于 Hive 数据库类实例有一个空locationUri
导致的异常属性字符串。这是因为 Glue 数据库没有 Location 属性 。保存架构后,Spark 从表中读取它。 - 可以通过设置
INFER_ONLY
来解决这个问题。 ,它应该只从文件中推断架构,而不是尝试更改表SERDEPROPERTIES
。但是,由于 Spark 错误,这不起作用,其中推断的架构会小写(请参阅 here )。
原始解决方案(不正确)
发生此错误是因为 Glue 表的 SERDEPROPERTIES
缺少两个重要属性:
-
spark.sql.sources.schema.numParts
-
spark.sql.sources.schema.part.0
为了解决这个问题,我必须通过 Glue 控制台添加这两个属性(无法使用 ALTER TABLE …
来做到这一点)
我猜这是 Glue 爬虫的一个错误,它在创建表时不会设置这些属性。
关于scala - 无法读取 Parquet 支持的区分大小写的 Glue 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59774349/