json数组会产生一行null

lf3rwulv  于 2021-05-26  发布在  Spark
关注(0)|答案(0)|浏览(221)

我在使用azuredatabricks将json文件处理成sparkDataframe时遇到了一个奇怪的问题。json文件本身由一个结构(对象)数组组成,对象很复杂,包括嵌套的数组/结构。
在将json加载到dataframe之后,我想分解“key\u list”,它的值是一个structs数组。当我只包含“id”值时,我的dataframe select返回了100行,但是当我将“key\u list”添加到select时,结果是一行空值。尽管事实上dataframe似乎已经正确地推断出了模式。
下面是一些代码来重新创建这个问题(简化为在数组中只包含2个顶级对象),我附加了一个在azuredatabricks中运行这个程序时看到的结果的屏幕截图。有人能识别是什么导致数据丢失,而不是返回两行的两个id值和第二列中表示为数组的键列表吗?

source_json = """
[
    {
        "id": 1,
        "key_list": [
            {
                "obj_key_id": "bp_nr",
                "val": "90000804",
                "prio": "",
                "ref_obj_id": "",
                "rule_id": "",
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_sym",
                "val": "CCC.CRST.BDJ02",
                "prio": "",
                "ref_obj_id": "",
                "rule_id": "",
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_swift",
                "val": "CRSTGB22XXX",
                "prio": "",
                "ref_obj_id": "",
                "rule_id": 1,
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_swift",
                "val": "CRSTGB20XXX",
                "prio": "0100",
                "ref_obj_id": "",
                "rule_id": 2,
                "rule_templ_id": "",
                "seq_nr": 2,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_clr",
                "val": "BDJ02",
                "prio": "1000",
                "ref_obj_id": 45046,
                "rule_id": 1,
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            }
        ]
    },
    {
        "id": 2,
        "key_list": [
            {
                "obj_key_id": "bp_nr",
                "val": "90000804",
                "prio": "",
                "ref_obj_id": "",
                "rule_id": "",
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_sym",
                "val": "CCC.CRST.BDJ02",
                "prio": "",
                "ref_obj_id": "",
                "rule_id": "",
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_swift",
                "val": "CRSTGB22XXX",
                "prio": "",
                "ref_obj_id": "",
                "rule_id": 1,
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_swift",
                "val": "CRSTGB20XXX",
                "prio": "0100",
                "ref_obj_id": "",
                "rule_id": 2,
                "rule_templ_id": "",
                "seq_nr": 2,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            },
            {
                "obj_key_id": "bp_clr",
                "val": "BDJ02",
                "prio": "1000",
                "ref_obj_id": 45046,
                "rule_id": 1,
                "rule_templ_id": "",
                "seq_nr": 1,
                "trig_meta_typ_id": "",
                "trig_order_type_id": ""
            }
        ]
    }
]
"""

dbutils.fs.put(file="/tmp/source.json", contents=source_json)

source_df = spark.read.option("multiline", "true").json(path="/tmp/source.json")
display(source_df)

结果截图
更新:我已经确定根本原因是键列表属性ref\u obj\u id和rule\u id的推断模式,这两个属性都被推断为long类型。如果我手动双引号引用通过的整数值,则推断的模式将这些值键入string,然后一切正常。我也可以通过手动构造一个模式并在spark.read中应用该模式来获得相同的结果。
但是,编辑源文件或手动构建模式并不理想,特别是在这个特定示例中的模式代表了一种简化,而真正的模式比这个要大得多、复杂得多。我想使用spark.read来推断一个模式,然后在一个字符串变量中捕获该模式,强制将模式定义中的每个非字符串简单类型更改为string,然后使用这个动态生成的schema string变量来创建一个实际的模式,然后我可以通过第二个spark.read调用来使用它。这是可能的吗(基本上是利用来自某个源文件的自动模式推断,但强制该模式的每一个简单类型都是类型化的字符串),如果是的话,如何实现这一点?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题