Search code examples
pythonjsonjmespath

JMESPath dictionary keys start with @


I'm having trouble writing a JMESPath query when some of my dictionary keys start with @.

I have this code:

    with open('foobar.json', 'r') as fp:
        data = json.load(fp)
    path = jmespath.search('[].record|[?value==`a`]', data)
    pp.pprint(path)

That reads this file (foobar.json):

[
  {"record":{"@type":"FOO", "value": "a"}},
  {"record":{"@type":"BAR", "value": "b"}},
  {"record":{"@type":"BAZ", "value": "c"}}
]

and outputs:

[{'@type': 'FOO', 'value': 'a'}]

as expected.

But, when I change the expression to:

    path = jmespath.search('[].record|[?@type==`FOO`]', data)

I get an exception

  File "/Users/msarrel/PycharmProjects/SISs/.venv/lib/python3.10/site-packages/jmespath/parser.py", line 488, in _raise_parse_error_maybe_eof
    raise exceptions.ParseError(
jmespath.exceptions.ParseError: Expecting: rbracket, got: unquoted_identifier: Parse error at column 13, token "type" (UNQUOTED_IDENTIFIER), for expression:
"[].record|[?@type==`FOO`]"
              ^

I've tried several variations including:

    path = jmespath.search('[].record|[?\@type==`FOO`]', data)
    path = jmespath.search('[].record|[?\\@type==`FOO`]', data)
    path = jmespath.search('[].record|[?\u0040type==`FOO`]', data)

But no success.

Any ideas?

I am not at liberty to get rid of the @ in the dictionary keys.


Solution

  • The following does the trick:

        path = jmespath.search('[].record|[?"@type"==`FOO`]', data)
    

    And, yields this result:

    [{'@type': 'FOO', 'value': 'a'}]