【问题标题】:iterate Json Array with Apache Nifi or Python script使用 Apache Nifi 或 Python 脚本迭代 Json 数组
【发布时间】:2020-07-31 15:40:58
【问题描述】:

我有一个带有 Array 字段的 Json,我想迭代该数组并将其拆分为 Array 中包含的每个属性的新行或对象。

我目前正在使用 Apache Nifi,但我也可以使用 python 脚本。

我的输入数据是:

{
  "workorder_id" : "99999",
  "properties" : [ {
    "id" : "11",
    "propertyType" : {
      "id" : "55834595398",
      "name" : "action"
    },
    "stringValue" : "string01",
    "nodeValue" : null
  }, {
    "id" : "22",
    "propertyType" : {
      "id" : "55834595419",
      "name" : "Tipo"
    },
    "stringValue" : "string02",
    "nodeValue" : null
  }, {
    "id" : "33",
    "propertyType" : {
      "id" : "44",
      "name" : "Action2"
    },
    "stringValue" : "string02",
    "nodeValue" : null
  }, {
    "id" : "55",
    "propertyType" : {
      "id" : "55834595400",
      "name" : "Action3"
    }
]
}

输出可以是 Json 或 csv。例如在 csv 中: 使用与 key 相同的 workorder_id

workorder_id,id_properties,stringValue_properties
99999,11,string01
99999,22,string02
99999,33,string03
.
.
.

感谢您的帮助

【问题讨论】:

    标签: python arrays json apache-nifi


    【解决方案1】:

    使用 NiFi

    按此顺序:

    1. EvaluateJsonPath 从 workorder_id ($.workorder_id) 创建属性

    2. 输出将其发送到$.properties.*上的Split Json

    3. splitjson 的输出将其发送到 evaluatejson,您将在其中提取数组。

      id = $.id
      propertyType_id = $.propertyType.id
      propertyType_name = $.propertyType.name
      

    现在您的每个流程都将带有此属性:

    workorder_id,id,propertyType_id,propertyType_name
    
    1. 使用此列表使用 AttributestoCSV

      workorder_id,id,propertyType_id,propertyType_name

    2. 合并内容

    3. putfile(保存你的 csv)

    【讨论】:

    • 感谢指导,我使用了 EvaluateJsonPath -> SplitJson -> QueryRecord -> ConvertJSONToSQL
    • 这实际上是更干净的方法!我不想深入研究记录解析器,因为这是一个更难的话题 - 但这是最​​佳方法,因为 split 将 folws 放入内存中而记录解析器不
    【解决方案2】:
    # -*- coding: utf-8 -*-
    
    data = {
      "workorder_id" : "99999",
      "properties" : [ 
      {
        "id" : "11",
        "propertyType" : {
          "id" : "55834595398",
          "name" : "action"
        },
        "stringValue" : "string01",
        "nodeValue" : float('nan')
      }, 
      {
        "id" : "22",
        "propertyType" : {
          "id" : "55834595419",
          "name" : "Tipo"
        },
        "stringValue" : "string02",
        "nodeValue" : float('nan')
      }, 
      {
        "id" : "33",
        "propertyType" : {
          "id" : "44",
          "name" : "Action2"
        },
        "stringValue" : "string03",
        "nodeValue" : float('nan')
      }, 
      {
        "id" : "55",
        "propertyType" : {
          "id" : "55834595400",
          "name" : "Action3"
          },
        "stringValue" : "string04",
        "nodeValue" : float('nan')
      }
    ]
    }
    
    for item in data['properties']:
        print(data['workorder_id'], item['id'], item['propertyType']['id'], item['propertyType']['name'], item['stringValue'], item['nodeValue'])
        
    
    #99999 11 55834595398 action string01 nan
    #99999 22 55834595419 Tipo string02 nan
    #99999 33 44 Action2 string03 nan
    #99999 55 55834595400 Action3 string04 nan
    

    【讨论】:

      【解决方案3】:

      您需要将这些空值转换为 None 或其他 Python 类型。

      假设您将空值切换为无...

      data = {'workorder_id': '99999', 'properties': [{'id': '11', 'propertyType': {'id': '55834595398', 'name': 'action'}, 'stringValue': 'string01', 'nodeValue': None}, {'id': '22', 'propertyType': {'id': '55834595419', 'name': 'Tipo'}, 'stringValue': 'string02', 'nodeValue': None}]}
      
      def _handler(prepend: str, record: dict):
          """ relabels keys with a prepended string """
          d = {}
          for key in record.keys():
              new_key = '%s_%s' % (prepend, key)
              d.update({new_key: record[key]})
          return d
      
      def mapper(data: dict):
          """ returns a list of dictionaries. """
          records= []
          properties = data['properties']
          for prop in properties:
              _record = {'workorder_id': data['workorder_id'], }
              
              for prop_key in prop.keys():
                  prop_data = {}
      
                  value = prop[prop_key]
                  if isinstance(value, dict):
                      prop_data.update(_handler(prop_key, value))
                  else:
                      prop_data.update({prop_key: value})
      
                  _record.update(_handler('property', prop_data))
              records.append(_record)
          return records
      

      输出

      [{'workorder_id': '99999',
        'property_id': '11',
        'property_propertyType_id': '55834595398',
        'property_propertyType_name': 'action',
        'property_stringValue': 'string01',
        'property_nodeValue': None},
       {'workorder_id': '99999',
        'property_id': '22',
        'property_propertyType_id': '55834595419',
        'property_propertyType_name': 'Tipo',
        'property_stringValue': 'string02',
        'property_nodeValue': None}]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多