在使用Azure DataRicks将JSON文件处理为Spark数据帧时,我遇到了一个奇怪的问题。JSON文件本身由一组结构(对象)组成,对象很复杂,包括嵌套的数组/结构
将JSON加载到数据帧后,我想分解“key_list”,其值是一个结构数组。当我只包含“id”值时,我的DataFrame select返回了100行,但一旦我将“key_list”添加到select中,结果就是一行空值。尽管DataFrame似乎已经正确地推断出了模式,但仍然存在这种情况
下面是一些重新创建问题的代码(简化为在数组中只包含两个顶级对象),我附上了一个在Azure Databricks中运行时看到的结果的屏幕截图。任何人都可以识别导致数据丢失的原因,而不是在第二列中返回两行的两个id值和表示为数组的key_列表吗
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)
更新: 我已经确定根本原因是key_list属性ref_obj_id和rule_id的推断模式,这两个属性都被推断为Long类型。如果我手动双引号引用通过的整数值,推断出的模式会将这些值键入字符串,然后一切正常。我还可以通过手动构建模式并在spark.read中应用该模式来实现相同的结果
但是,编辑源文件或手动构建模式并不理想,特别是因为此特定示例中的模式表示一种简化,而真正的模式比此要大得多、复杂得多。我想使用spark.read推断一个模式,然后在一个字符串变量中捕获该模式,在模式定义中将每个非字符串简单类型强制更改为字符串,然后使用这个动态生成的模式字符串变量创建一个实际的模式,然后通过第二个spark.read调用使用该模式。这是可能的(基本上是利用来自某个源文件的自动模式推断,但强制该模式的每个简单类型都是字符串类型),如果是,如何实现
目前没有回答
相关问题 更多 >
编程相关推荐