Spark from_json没有例外

时间:2019-02-06 09:49:26

标签: json scala apache-spark

我正在使用Spark 2.1(scala 2.11)。

我想使用已定义的架构将json格式的字符串从一个数据帧加载到另一个数据帧中。 我已经尝试了一些解决方案,但最便宜的是标准列函数from_json。 我尝试了使用此功能的示例(https://jaceklaskowski.gitbooks.io/mastering-spark-sql/spark-sql-functions-collection.html#from_json),该示例给我带来意想不到的结果。

val df = spark.read.text("testFile.txt")

df.show(false)

+----------------+
|value           |
+----------------+
|{"a": 1, "b": 2}|
|{bad-record     |
+----------------+


df.select(from_json(col("value"),
      StructType(List(
                  StructField("a",IntegerType),
                  StructField("b",IntegerType)
                ))
    )).show(false)


+-------------------+
|jsontostruct(value)|
+-------------------+
|[1,2]              |
|null               |
+-------------------+

此行为类似于mode:PERMISSIVE,这不是默认值。 默认情况下,它设置为FAILFAST模式,这意味着只要输入数据和强制模式不匹配,它都应该引发异常。

我尝试使用DataFrameReader(JSON数据源和FAILFAST模式)加载testFile.txt并成功捕获异常。

spark.read.option("mode","FAILFAST").json("test.txt").show(false)

---
Caused by: org.apache.spark.sql.catalyst.json.SparkSQLJsonProcessingException: Malformed line in FAILFAST mode: {bad-record
---

尽管两种情况下的解析模式都相同,但为什么各自的输出却如此不同?

2 个答案:

答案 0 :(得分:0)

这是预期的行为。 from_json是一种SQL函数,在此级别上没有异常(故意的)概念。如果操作失败,则结果不确定NULL

尽管from_json提供了options参数,该参数允许您设置JSON阅读器选项,但由于上述原因,这种行为不能被覆盖。

在旁注中,DataFrameReader的默认模式是允许的。

答案 1 :(得分:0)

请注意,您正在将文件读取为文本文件并将其转换为json。默认情况下,如果您具有有效的JSON字符串,则换行符将成为文本文件的分隔符,并且在一行中,换行符将与您在from_json()方法中定义的架构正确转换。

如果有空行或无效的JSON文本,则将得到NULL。

检查一下:

val df = spark.read.text("in/testFile.txt")
println("Default show()")
df.show(false)

println("Using the from_json method ")
df.select(from_json(col("value"),
  StructType(List(
    StructField("a",IntegerType),
    StructField("b",IntegerType)
  ))
)).show(false)

当in / testFile.txt中包含以下内容时,

{"a": 1, "b": 2 }

它打印

Default show()
+-----------------+
|value            |
+-----------------+
|{"a": 1, "b": 2 }|
+-----------------+

Using the from_json method 
+--------------------+
|jsontostructs(value)|
+--------------------+
|[1,2]               |
+--------------------+

当您输入的内容为空行

{"a": 1, "b": 2 }
// Blank line

结果是

Default show()
+-----------------+
|value            |
+-----------------+
|{"a": 1, "b": 2 }|
|                 |
+-----------------+

Using the from_json method 
+--------------------+
|jsontostructs(value)|
+--------------------+
|[1,2]               |
|null                |
+--------------------+