当我在spark-shell上查询dataframes(1.6版本)时,列名称不敏感。在火花壳上
val a = sqlContext.read.parquet("<my-location>")
a.filter($"name" <=> "andrew").count()
a.filter($"NamE" <=> "andrew").count()
以上结果使我有正确的计数。但是,当我在罐子中构建它并通过" spark-submit"运行时,下面的代码失败说名称不存在,因为基础木木木的数据被用作"名称"
将列保存为失败:
a.filter($"NamE" <=> "andrew").count()
通过:
a.filter($"name" <=> "andrew").count()
我在这里错过了一些东西吗?有什么方法可以使它不敏感。我知道我可以在过滤之前使用选择,并将所有列作为小写别名,但想知道为什么它的行为不同。
这有点棘手:平淡的答案是因为您认为在两种情况下都在使用相同的SQLContext
,实际上,您不是。在Spark-Shell中,为您创建了一个SQLContext,但实际上是HiveContext
:
scala> sqlContext.getClass
res3: Class[_ <: org.apache.spark.sql.SQLContext] = class org.apache.spark.sql.hive.HiveContext
在您的火花床中,您可能会使用简单的SQLContext
。根据 @LostInoverflow的链接:Hive is case insensitive, while Parquet is not
,所以我的猜测是:通过使用HiveContext
,您可能会使用与Hive相关的某些代码来下载Parquet数据。蜂巢不敏感,效果很好。使用简单的SQLContext
,它不是,这是预期的行为。
您缺少的部分:
...是不敏感的,而镶木不是
您可以尝试:
val b = df.toDF(df.columns.map(_.toLowerCase): _*)
b.filter(...)
尝试用SQLContext明确控制情况敏感性。使用以下语句关闭案例灵敏度,并检查是否有帮助。
sqlContext.sql("set spark.sql.caseSensitive=false")