Search code examples
pythonyamlpyyaml

How do I configure multiple dictionary keys in a yaml file in Python?


I am trying to use a yaml file to store dictionary keys so I can parse various json payloads.

I have the following yaml file loaded into a variable called 'cfg':

my_table: metadata

When I run:

for i in json['resources']:
    print(i[cfg['my_table']])

I can see all values from my json's ['metadata'] keys just fine.

However, I would like to see all values from the ['metadata']['guid'] keys that exist under ['resources']. So when I change my yaml file to:

my_table: metadata, guid

It doesn't work. I've also tried these variations:

my_table: ['metadata', 'guid']  #tried ''.join("['{0}']".format(a) for a in cfg['my_table']) which gives me what I want, but when I shove this inside i[], I get a key error
my_table: ['metadata']['guid']  #yaml file doesn't parse properly

Any ideas?


Solution

  • So you want to store dictionary keys in a yaml file?

    Just do

    # keys.yaml
    my_table: [metadata, guid]
    

    And then in your python file

    keys = yaml.safe_load('keys.yaml')['my_table']
    
    for obj in json['resources']:  # don't call it json, that's a package name
        print(obj[keys[0]][keys[1]])
    

    For a variable number of keys (not only two) do it like so:

    def recursive_getitem(obj, keys):
       if len(keys) == 0:
          return obj
       return recursive_getitem(obj[keys[0]], keys[1:])
    

    and then do

    for obj in json['resources']:  
        print(recursive_getitem(obj, keys))
    

    To answer your second question in the comments, you need to use a nested list

    # keys.yaml
    my_table:
        - [metadata, guid]
        - [entity, name]
    

    .

    # py file
    keys = yaml.safe_load('keys.yaml')['my_table']
    
    for obj in json['resources']:  # don't call it json, that's a package name
        print(obj[keys[0][0]][keys[0][1]])
        print(obj[keys[1][0]][keys[1][1]])