我正在从s3数据湖中抓取以下JSON文件(这是有效的JSON)。 内部有2个字段(设备,时间戳)和一个称为“数据”的对象数组。数据数组中的每个对象都互不相同。
{"device":"0013374838793C8","timestamp":"2019-03-04T14:44:39Z","data":[ { "eparke_status":"09"}, { "eparke_x":"FFF588"}, { "eparke_y":"000352"}, { "eparke_z":"000ACC"}, { "eparke_temp":"14.00"}, { "eparke_voltage":"4.17"} ] }
不幸的是,当我使用AWS Glue进行爬网时,无法正确推断出爬网器架构,而我在Athena中得到的也不是我所期望的。
以下清单显示了来自AWS Athena的一行数据。
1 0013374838793C8 2019-03-05T13:11:41Z [{eparke_status=0B, eparke_x=null, eparke_y=null, eparke_z=null, eparke_temp=null, eparke_voltage=null}, {eparke_status=null, eparke_x=FFF6D4, eparke_y=null, eparke_z=null, eparke_temp=null, eparke_voltage=null}, {eparke_status=null, eparke_x=null, eparke_y=000133, eparke_z=null, eparke_temp=null, eparke_voltage=null}, {eparke_status=null, eparke_x=null, eparke_y=null, eparke_z=000DA3, eparke_temp=null, eparke_voltage=null}, {eparke_status=null, eparke_x=null, eparke_y=null, eparke_z=null, eparke_temp=14.00, eparke_voltage=null}, {eparke_status=null, eparke_x=null, eparke_y=null, eparke_z=null, eparke_temp=null, eparke_voltage=4.17}]
如您所见,在数组模式中的每个对象都是“错误地”发现的。 DB中的每一列都包含所有数组对象字段,大多数字段都被设置为null,这是可以理解的,因为找不到它们。发现的架构不是我想要的。
期望
以下列表显示了使用AWS Glue进行爬网后表的预期形式。
1 0013374838793C8 2019-03-05T13:11:41Z eparke_status=0B eparke_x=FFF6D4 eparke_y=000133 eparke_z=000DA3 eparke_temp=14.00 eparke_voltage=4.17
到目前为止我尝试过什么?
AWS胶水分类器 为了强制模式,我尝试使用分类器。
$.device $.timestamp $.eparke_status $.eparke_x $.eparke_y $.eparke_z $.eparke_temp $.eparke_voltage
和
$.device $.timestamp $.data[0].eparke_status $.data[1].eparke_x $.data[2].eparke_y $.data[3].eparke_z $.data[4].eparke_temp $.data[5].eparke_voltage
仍然,最终模式看起来相同-所有对象都包装在每一列中。
任何想法如何解决此问题? 我还尝试使用自定义脚本配置ETL作业,但到目前为止仍失败。
答案 0 :(得分:0)
我注意到的一件事是,搜寻器一旦运行一次,最初推断的架构和选定的搜寻器在新运行时就不会改变。我只是认为复制游标并在玩耍时删除任何以前创建的表更安全。
我不确定您可以在Json分类器表达式中连接多个根表达式。文档说,对于JSON分类器,您只需要提供指向每行节点的THE路径,该路径将被视为从中推断模式的实际json
要使用数组的每个元素来推断模式,必须使用$ .data [*]。但这意味着您会错过设备和时间戳。
您不能仅通过搜寻器来执行此操作。我的建议是不使用自定义分类器进行分析,然后使用Athena查询(https://docs.aws.amazon.com/athena/latest/ug/flattening-arrays.html)从数组结构中删除数据。如果需要,将结果加载到某个数据存储区。对于S3,将CTAS作为一个选项。您也许还可以将其配置为ETL作业