【问题标题】:Spark DataFrame column name case sensitivity in sparkSQL and Spark SubmitsparkSQL 和 Spark Submit 中的 Spark DataFrame 列名区分大小写
【发布时间】:2017-04-26 02:19:28
【问题描述】:

当我在 spark-shell(1.6 版本) 上查询数据帧时,列名不区分大小写。 在 Spark-Shell 上

 val a = sqlContext.read.parquet("<my-location>")
   a.filter($"name" <=> "andrew").count()
   a.filter($"NamE" <=> "andrew").count()

以上两个结果都给了我正确的计数。 但是当我在一个 jar 中构建它并通过“spark-submit”运行时,下面的代码失败说 NameE 不存在,因为底层镶木地板数据被保存为“name”列

失败:

a.filter($"NamE" <=> "andrew").count()

通过:

a.filter($"name" <=> "andrew").count()

我在这里遗漏了什么吗?有没有办法让它不区分大小写。 我知道我可以在过滤之前使用 select 并将所有列设为小写别名,但想知道为什么它的行为不同。

【问题讨论】:

    标签: apache-spark apache-spark-sql


    【解决方案1】:

    这里有点棘手:简单的答案是因为您认为您在两种情况下都使用相同的SQLContext,而实际上您并没有。在 spark-shell 中,为你创建了一个 SQLContext,但它实际上是一个HiveContext

    scala> sqlContext.getClass res3: Class[_ <: org.apache.spark.sql.SQLContext] = class org.apache.spark.sql.hive.HiveContext

    在您的 spark-submit 中,您可能使用了一个简单的 SQLContext。根据@LostInOverflow 的链接:Hive is case insensitive, while Parquet is not,所以我的猜测如下:通过使用HiveContext,您可能正在使用与 Hive 关联的一些代码来下载您的 Parquet 数据。 Hive 不区分大小写,它工作正常。使用简单的SQLContext,它不会,这是预期的行为。

    【讨论】:

    • 使用 HiveContext 代替 SQLContext 解决了这个问题。另外如果你想使用 SQLContext,那么我们可以使用 sqlContext.setConf("spark.sql.caseSensitive","false"),这样它就变成了大小写不敏感
    • 不知道sqlContext.setConf("spark.sql.caseSensitive","false"),很好。
    【解决方案2】:

    The part you're missing:

    ... 不区分大小写,而 Parquet 不区分

    你可以试试:

    val b = df.toDF(df.columns.map(_.toLowerCase): _*)
    b.filter(...)
    

    【讨论】:

    • 那为什么当我通过 spark-shell 查询相同的 parquet 数据时它会起作用?
    • 我不知道。
    【解决方案3】:

    尝试使用 sqlContext 显式控制区分大小写。 使用以下语句关闭区分大小写并检查它是否有帮助。

    sqlContext.sql("set spark.sql.caseSensitive=false")

    【讨论】:

      猜你喜欢
      • 2019-02-07
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 2016-03-06
      • 2019-03-02
      相关资源
      最近更新 更多