Искра от _json Без исключений - PullRequest
0 голосов
/ 06 февраля 2019

Я работаю со 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               |
+-------------------+

Это поведение похоже на режим: PERMISSIVE, который не является значением по умолчанию. По умолчанию этоустановлен в режим FAILFAST, что означает, что он должен выдавать исключение, когда входные данные и принудительная схема не совпадают.

Я попытался загрузить testFile.txt с DataFrameReader (режим JSON DataSource и FAILFAST) и успешно перехватил исключение.

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 голосов
/ 06 февраля 2019

Обратите внимание, что вы читаете файл как текстовый файл и конвертируете его в 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                |
+--------------------+
0 голосов
/ 06 февраля 2019

Это ожидаемое поведение.from_json - это функция SQL, и на этом уровне нет понятия исключения (преднамеренного).Если операция завершается неудачно, результат не определен NULL.

Хотя from_json предоставляет аргумент options, который позволяет установить опцию чтения JSON, это поведение по причине, указанной выше, не может быть переопределено.

В режиме примечания по умолчанию для DataFrameReader разрешен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...