from_json إرجاع null في اباتشي سبارك 3.0

مشكلة

from_jsonيتم استخدام الدالة تحليل سلسلة JSON وإرجاع هيكل القيم.

على سبيل المثال، إذا كان لديك سلسلة JSON [{"id":"001","name":"peter"}] ، يمكنك تمريرها إلى from_json مع مخطط والحصول على قيم البنية تحليل في الإرجاع.

from pyspark.sql.functions import col, from_json
display(
  df.select(col('value'), from_json(col('value'), json_df_schema, {"mode" : "PERMISSIVE"}))
)

في هذا المثال، يحتوي إطار البيانات على عمود "قيمة"، مع محتويات [{"id":"001","name":"peter"}] والمخطط هو StructType(List(StructField(id,StringType,true),StructField(name,StringType,true))) .

يعمل هذا بشكل صحيح على Spark 2.4 و أقل (Databricks وقت التشغيل 6.4 ES و أدناه).

* id:
  "001"
* name:
  "peter"

هذا إرجاع القيم الخالية على 3.0 Spark وما فوق (Databricks وقت التشغيل 7.3 LTS وما فوق).

* id:
  null
* name:
  null

السبب

يحدث هذا لأن Spark 3.0 وما فوق لا يمكن تحليل صفائف JSON كما البنيات.

يمكنك تأكيد ذلك عن طريق تشغيل from_json في FAILFAST الوضع.

from pyspark.sql.functions import col, from_json
display(
  df.select(col('value'), from_json(col('value'), json_df_schema, {"mode" : "FAILFAST"}))
)

هذا بإرجاع رسالة خطأ الذي يعرف السبب الجذري.

Caused by: RuntimeException: Parsing JSON arrays as structs is forbidden

حل

يجب تمرير المخطط ArrayType بدلا من StructType في Databricks وقت التشغيل 7.3 LTS وما فوق.

from pyspark.sql.types import StringType, ArrayType, StructType, StructField
schema_spark_3 = ArrayType(StructType([StructField("id",StringType(),True),StructField("name",StringType(),True)]))

from pyspark.sql.functions import col, from_json
display(
  df.select(col('value'), from_json(col('value'), schema_spark_3, {"mode" : "PERMISSIVE"}))
)

في هذا المثال التعليمات البرمجية، المخطط السابق StructType هو المضمنة في ArrayType ويتم استخدام المخطط الجديد مع from_json .

هذا يوزع سلسلة JSON بشكل صحيح وإرجاع القيم المتوقعة.