Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

merge two yaml files in python

I have two yaml files as mentioned below

test1.yaml

resources:
  server_group_1:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 5] }
      policies: [ { get_param: [server_group_types, 5] } ]

  server_group_2:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 8] }
      policies: [ { get_param: [server_group_types, 8] } ]
output:
  check_1:
    description: Name of the instance
    value: { get_attr: [check_1, vname] }

test2.yaml

resources:
  server_group_4:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 4] }
      policies: [ { get_param: [server_group_types, 4] } ]

  server_group_9:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 7] }
      policies: [ { get_param: [server_group_types, 7] } ]
output:
  check_6:
    description: Name of the instance
    value: { get_attr: [check_6, vname] }

I want to merge this two files and create a new output file ,so I use pyyaml the order is getting changed posted same in this link

Can someone help to merge these files without changing the order? Final yaml should be like this

final.yaml

resources:
  server_group_1:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 5] }
      policies: [ { get_param: [server_group_types, 5] } ]

  server_group_2:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 8] }
      policies: [ { get_param: [server_group_types, 8] } ]

  server_group_4:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 4] }
      policies: [ { get_param: [server_group_types, 4] } ]

  server_group_9:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 7] }
      policies: [ { get_param: [server_group_types, 7] } ]
output:
  check_1:
    description: Name of the instance
    value: { get_attr: [check_1, vname] }

  check_6:
    description: Name of the instance
    value: { get_attr: [check_6, vname] } 

Updated

I am able to merge files using ruamel.yaml ... here goes the sample code to update resources

code:

import ruamel.yaml
yaml = ruamel.yaml.YAML()
#Load the yaml files
with open('/test1.yaml') as fp:
    data = yaml.load(fp)
with open('/test2.yaml') as fp:
    data1 = yaml.load(fp)
#Add the resources from test2.yaml to test1.yaml resources
for i in data1['resources']:
    print i,data1['resources'][i]
    data['resources'].update({i:data1['resources'][i]})
#create a new file with merged yaml
yaml.dump(data,file('/tmp/lal.yaml', 'w'))
like image 491
Naresh Avatar asked Jan 04 '23 04:01

Naresh


2 Answers

Below sample code worked well for me to merge two yaml file

import ruamel.yaml
yaml = ruamel.yaml.YAML()
#Load the yaml files
with open('/test1.yaml') as fp:
    data = yaml.load(fp)
with open('/test2.yaml') as fp:
    data1 = yaml.load(fp)
#Add the resources from test2.yaml to test1.yaml resources
for i in data1['resources']:
    print i,data1['resources'][i]
    data['resources'].update({i:data1['resources'][i]})
#create a new file with merged yaml
yaml.dump(data,file('/tmp/lal.yaml', 'w'))
like image 195
Naresh Avatar answered Jan 15 '23 00:01

Naresh


An alternative solution is to use HiYaPyCo (https://pypi.org/project/HiYaPyCo/), which implements a merge preserving an order of elements.

import hiyapyco

yaml1 = """resources:
  server_group_1:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 5] }
      policies: [ { get_param: [server_group_types, 5] } ]

  server_group_2:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 8] }
      policies: [ { get_param: [server_group_types, 8] } ]
output:
  check_1:
    description: Name of the instance
    value: { get_attr: [check_1, vname] }"""

yaml2 = """resources:
  server_group_4:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 4] }
      policies: [ { get_param: [server_group_types, 4] } ]

  server_group_9:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 7] }
      policies: [ { get_param: [server_group_types, 7] } ]
output:
  check_6:
    description: Name of the instance
    value: { get_attr: [check_6, vname] }"""

merged_yaml = hiyapyco.load([yaml1, yaml2], method=hiyapyco.METHOD_MERGE)
print(hiyapyco.dump(merged_yaml))

Output:

resources:
  server_group_1:
    type: OS::Nova::ServerGroup
    properties:
      name:
        get_param: [server_groups, 5]
      policies:
      - get_param: [server_group_types, 5]
  server_group_2:
    type: OS::Nova::ServerGroup
    properties:
      name:
        get_param: [server_groups, 8]
      policies:
      - get_param: [server_group_types, 8]
  server_group_4:
    type: OS::Nova::ServerGroup
    properties:
      name:
        get_param: [server_groups, 4]
      policies:
      - get_param: [server_group_types, 4]
  server_group_9:
    type: OS::Nova::ServerGroup
    properties:
      name:
        get_param: [server_groups, 7]
      policies:
      - get_param: [server_group_types, 7]
output:
  check_1:
    description: Name of the instance
    value:
      get_attr: [check_1, vname]
  check_6:
    description: Name of the instance
    value:
      get_attr: [check_6, vname]
like image 33
augur Avatar answered Jan 14 '23 22:01

augur