Spark SQL 嵌套 JSON 错误“输入时没有可行的替代方案”
Posted
技术标签:
【中文标题】Spark SQL 嵌套 JSON 错误“输入时没有可行的替代方案”【英文标题】:Spark SQL nested JSON error "no viable alternative at input " 【发布时间】:2019-06-01 20:38:53 【问题描述】:Spark SQL 嵌套 JSON 错误:
"xxxDetails":
"yyyData":
"0":
"additionalData":
,
"quantity":80000,
"www":12.6,
"ddd":5.0,
"eee":72000,
"rrr":false
,
"130":
"additionalData":
"quantity":1
,
"quantity":0,
"www":1.0,
"ddd":0.0,
"eee":0,
"rrr":false
,
"yyy":
"additionalData":
"quantity":1
,
"quantity":0,
"www":1.0,
"ddd":0.0,
"eee":0,
"rrr":false
,
"mmmDto":
"id":0,
"name":"",
"data":null
当读取 spark.sql("select cast (xxxDetails.yyyData.yyy.additionalData.quantity as Long) as quantity from table") 时,它会起作用,但是: spark.sql("select cast (xxxDetails.yyyData.130. additionalData.quantity as Long) as quantity from table") 将抛出异常:
org.apache.spark.sql.catalyst.parser.ParseException: 在输入'cast(xxxDetails.yyyData.130.
当我为 myDF.select("xxxDetails.yyyData.130.additionalData.quantity") 使用 datafame API 时,它的工作。 任何有体面解释的人:)
【问题讨论】:
【参考方案1】:这是因为 SQL 列名应以字母或其他字符(如 _
、@
或 #
)开头,但不能以数字开头。让我们考虑这个简单的例子:
Seq((1, 2)).toDF("x", "666").createOrReplaceTempView("test")
调用spark.sql("SELECT x FROM test").show()
会输出
+---+
| x|
+---+
| 1|
+---+
但调用 spark.sql("SELECT 666 FROM test").show()
代替输出
+---+
|666|
+---+
|666|
+---+
因为666
被解释为文字,而不是列名。要解决此问题,需要使用 backticks 引用列名:
spark.sql("SELECT `666` FROM test").show()
+---+
|666|
+---+
| 2|
+---+
【讨论】:
嗨@ollik1 抱歉,我正在用更多细节更新我的示例/问题,即使我使用该错误仍然存在:spark.sql("select cast (xxxDetails.'130'. yyy.quantity as Long) 作为数量。再次对第一个不完整的示例表示抱歉。 这对我有用,@ArnonRodman 请记住它不是单引号而是斜引号,即spark.sql("select cast (xxxDetails.yyyData.`130`.additionalData.quantity as Long) as quantity from table")
编辑答案以强调使用正确的引号字符
Thx @ollik1 和 Richard Nemeth 成功了,我在文档中哪里可以找到它?以及为什么 spark.sql API 与 DataFrame.sql API 不同
不确定是否有比 issues.apache.org/jira/browse/SPARK-3483 更好的文档,这会导致 github.com/apache/spark/pull/2804/files 。它没有解释为什么选择反引号而不是标准 SQL 的双引号。 Dataframe API 有所不同,因为它从方法签名中明确表明传递的字符串引用了一个列。但是,SQL 字符串需要按照一定的规则进行解析和分析。请注意,以数字开头的标识符在 Java、Scala 和 Python 中也会失败以上是关于Spark SQL 嵌套 JSON 错误“输入时没有可行的替代方案”的主要内容,如果未能解决你的问题,请参考以下文章
在 JAVA 中使用 Spark 2.1.1 读取嵌套 Json(Spark 2.2 有解决方案,但我正在研究 spark 2.1.1 版本)
我如何将平面数据框转换为 spark(scala 或 java)中的嵌套 json
使用 spark 展平嵌套的 json 文档并加载到 Elasticsearch