3

I am using the glom package to help with traversing a big dictionary.

Given this data:

data = {
    'groups': [
        {'instance': {'name': 'football'}},
        {'instance': {'name': 'rugby'}},
        {'id': 145, 'type': 'unknown'},
    ]
}

And using glom, I attempt to get the instance names:

import glom
instance_names = glom(data, ('groups', ['instance.name']))

I receive an Error:

glom.core.PathAccessError: could not access 'instance', part 0 of Path('instance', 'name'), got error: KeyError('instance')

How can I skip the objects where the instance key does not exist?

Update

I have tried to skip the exception but then I receive empty results:

instance_names = glom(data, ('groups', ['instance.name']), skip_exc=PathAccessError)
tread
  • 10,133
  • 17
  • 95
  • 170
  • Just by the way with `yaql` this can be achieved with: `$.groups.where($.containsKey("instance"))` – tread Jan 21 '20 at 09:24

1 Answers1

0

As per the documentation of glom API.

default (object) – An optional default to return in the case an exception, specified by skip_exc, is raised.

skip_exc (Exception) – An optional exception or tuple of exceptions to ignore and return default (None if omitted). If skip_exc and default are both not set, glom

So

instance_names = glom(data, ('groups', ['instance.name']), skip_exc=PathAccessError)

will return the default(None) when it encounter PathAccessError Exception. Here is the relevant part of the source code which explain this.

default = kwargs.pop('default', None if 'skip_exc' in kwargs else _MISSING)
skip_exc = kwargs.pop('skip_exc', () if default is _MISSING else GlomError)
...
...
try:
    ret = _glom(target, spec, scope)
except skip_exc:
    if default is _MISSING:
        raise
    ret = default

Here is one way you can solve this problem.

Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from glom import glom, SKIP
>>>
>>> data = {
...     'groups': [
...         {'instance': {'name': 'football'}},
...         {'instance': {'name': 'rugby'}},
...         {'id': 145, 'type': 'unknown'},
...     ]
... }
>>>
>>> instance_names = glom(data, ('groups', [lambda x: glom(x, 'instance.name', default=SKIP)]))
>>> print(instance_names)
['football', 'rugby']

The SKIP singleton can be returned from a function or included via a Literal to cancel assignment into the output object.

Abdul Niyas P M
  • 18,035
  • 2
  • 25
  • 46