【问题标题】:Cannot read case-sensitive Glue table backed by Parquet无法读取 Parquet 支持的区分大小写的 Glue 表
【发布时间】:2020-05-03 13:46:28
【问题描述】:

Spark 版本:Amazon EMR 5.24.0 上的 2.4.2

我有一个由 S3 Parquet 目录支持的 Glue 目录表。 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

【问题讨论】:

    标签: scala apache-spark hive parquet aws-glue-data-catalog


    【解决方案1】:

    编辑

    以下解决方案不正确。

    1. Glue Crawlers 不应该设置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 会从表中读取它。
    2. 可以通过设置INFER_ONLY 来解决这个问题,它应该只从文件中推断架构而不尝试更改表SERDEPROPERTIES。但是,由于 Spark 错误,这不起作用,其中推断的架构随后被小写(请参阅here)。

    原解(不正确)

    发生此错误是因为 Glue 表的 SERDEPROPERTIES 缺少两个重要属性:

    • spark.sql.sources.schema.numParts
    • spark.sql.sources.schema.part.0

    为了解决这个问题,我不得不通过 Glue 控制台添加这两个属性(不能用 ALTER TABLE … 做到这一点)

    我猜这是 Glue 爬虫的错误,它在创建表时没有设置这些属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 2017-10-20
      • 1970-01-01
      • 2016-11-24
      • 2021-04-16
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多