简体   繁体   English

词典列表中的词典列表的Glom规范

[英]Glom spec for list of dictionaries inside a list of dictionaries

I am currently using glom to parse through a JSON API response, which returns, among other things, a list of dictionaries, with a list of dictionaries inside it. 我目前正在使用glom来解析JSON API响应,该响应除其他外返回字典列表以及其中的字典列表。 The problem I'm having is getting glom to access the correct dictionary entry. 我遇到的问题是让glom访问正确的字典条目。

Example JSON: JSON示例:

{'answeredAt': '2019-08-23T21:11:04Z',
  'direction': 'Inbound',
  'disposition': 'Answered',
  'duration': 110867,
  'endedAt': '2019-08-23T21:12:55Z',
  'from': {'connectedAt': '2019-08-23T21:11:04Z',
   'departmentName': None,
   'deviceType': None,
   'disconnectedAt': '2019-08-23T21:12:55Z',
   'name': 'blah',
   'number': '1234567890',
   'number_e164': '1234567890',
   'serviceId': None,
   'userId': None},
  'initialQueueName': 'blah',
  'joinedLinkedIds': [],
  'legs': [{'departmentName': 'default',
    'deviceType': 'Unknown',
    'legType': 'Dial',
    'menuName': None,
    'menuOption': None,
    'menuPrompt': None,
    'number': '1234567890',
    'optionAction': None,
    'optionArg': None,
    'queueName': None,
    'serviceId': 327727,
    'timestamp': '2019-08-23T21:11:04Z',
    'userId': None},
   {'departmentName': 'default',
    'deviceType': 'Unknown',
    'legType': 'Answer',
    'menuName': None,
    'menuOption': None,
    'menuPrompt': None,
    'number': '1234567890',
    'optionAction': None,
    'optionArg': None,
    'queueName': None,
    'serviceId': 327727,
    'timestamp': '2019-08-23T21:11:04Z',
    'userId': None},
   {'departmentName': None,
    'deviceType': None,
    'legType': 'EnterIVR',
    'menuName': 'blah',
    'menuOption': None,
    'menuPrompt': None,
    'number': None,
    'optionAction': None,
    'optionArg': None,
    'queueName': None,
    'serviceId': None,
    'timestamp': '2019-08-23T21:11:05Z',
    'userId': None},
   {'departmentName': None,
    'deviceType': None,
    'legType': 'IVRSchedule',
    'menuName': 'Day',
    'menuOption': None,
    'menuPrompt': None,
    'number': None,
    'optionAction': None,
    'optionArg': None,
    'queueName': None,
    'serviceId': None,
    'timestamp': '2019-08-23T21:11:06Z',
    'userId': None},
   {'departmentName': None,
    'deviceType': None,
    'legType': 'EnterQueue',
    'menuName': None,
    'menuOption': None,
    'menuPrompt': None,
    'number': None,
    'optionAction': None,
    'optionArg': None,
    'queueName': 'blah',
    'serviceId': None,
    'timestamp': '2019-08-23T21:11:15Z',
    'userId': None},
   {'departmentName': None,
    'deviceType': None,
    'legType': 'Hangup',
    'menuName': None,
    'menuOption': None,
    'menuPrompt': None,
    'number': 'blah',
    'optionAction': None,
    'optionArg': None,
    'queueName': None,
    'serviceId': None,
    'timestamp': '2019-08-23T21:12:55Z',
    'userId': None}],
  'linkedId': 'some unique key',
  'startedAt': '2019-08-23T21:11:04Z',
  'to': {'connectedAt': '2019-08-23T21:11:04Z',
   'departmentName': 'default',
   'deviceType': 'Unknown',
   'disconnectedAt': '2019-08-23T21:12:55Z',
   'name': None,
   'number': '1234567890',
   'number_e164': '1234567890',
   'serviceId': 327727,
   'userId': None},
  'version': {'label': None, 'major': 4, 'minor': 2, 'point': 1}},

The information I'm trying to get at is in 'legs', where 'legType' == 'Dial' or 'EnterIVR'. 我想获取的信息在“ legs”中,其中“ legType” ==“ Dial”或“ EnterIVR”。 I need 'number' from the 'Dial' leg, and 'menuName' from the 'EnterIVR' leg. 我需要从“拨号”分支获取“数字”,并从“ EnterIVR”分支获取“ menuName”。 I can get it, for instance, to list back all the different legTypes, but not the data specifically from those. 例如,我可以列出所有不同的legType,但不能列出那些数据。

This is where I'm at currently: 这是我目前所在的位置:

with open('callstest.csv',mode='w') as calls:
    data_writer = csv.writer(calls, delimiter = ',')
    data_writer.writerow(['LinkedID','Number','Queue','Client'])
    target = response_json['calls']
    glomtemp = {}
    for item in target:
        spec = {
            'Linked ID':'linkedId',
            #this returns the number I need only in certain cases, 
            #so I need 'number' from the 'Dial' legType
            'Number': ('to', 'number') 
            'Queue': 'initialQueueName',
            'Client': #need help here, should be 'menuName' from
                      #'EnterIVR' legType
                }
        glomtemp = glom(item,spec)
        #print(glomtemp)
        data_writer.writerow([glomtemp['Linked ID'],glomtemp['Number'],glomtemp['Queue']])

Right now I can get them to fall back with Coalesce to "None", but that's not what I'm looking for. 现在,我可以让他们和Coalesce一起退到“无”,但这不是我想要的。

Any suggestions on how I should spec this to get the info out of those 2 legs for 'Number' and 'Client'? 关于如何指定此信息以从“数字”和“客户”的那两条腿中获取信息的任何建议?

If I understand correctly, you want to filter out certain entries that don't fit the supported legType . 如果我理解正确,则想过滤掉某些不支持受支持的legType You're definitely onto something with the Coalesce , and I think the key here is glom's Check specifier type , combined with the SKIP singleton . 您肯定会对Coalesce有所了解,我认为这里的关键是glom的Check指示符类型 ,结合SKIP单例 I had to tweak your current spec a bit to match the example data, but this runs: 我必须稍微调整一下您当前的规格以匹配示例数据,但这可以运行:

from glom import glom, Check, Coalesce, SKIP

LEG_SPEC = {'Client': Coalesce('menuName', default=''),
            'Number': Coalesce('to.number', default=''),
            'Linked ID': 'serviceId',
            'Queue': 'queueName'}
entries_spec = ('legs', 
                [Check('legType', one_of=('Dial', 'EnterIVR'), default=SKIP)],
                [LEG_SPEC])
pprint(glom(target, entries_spec))
# prints:
# [{'Client': None, 'Linked ID': 327727, 'Number': '', 'Queue': None},
#  {'Client': 'blah', 'Linked ID': None, 'Number': '', 'Queue': None}]

Not sure if that was exactly what you were hoping to see, but the pattern is there. 不知道那是否正是您希望看到的,但是模式在那里。 I think you want None s (or '' ) for those other fields because the csv you're writing is going to want to put something in those columns. 我认为您需要为其他字段提供None (或'' ),因为您正在编写的csv将要在这些列中添加一些内容。

There are other ways of doing filtered iteration using glom, too. 还有其他使用glom进行滤波迭代的方法。 The snippets page has a short section , complete with examples. 摘录页面有一个简短的部分 ,并附有示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM