merge two yaml files in python
Asked Answered
T

2

7

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'))
Tobey answered 22/11, 2017 at 0:15 Comment(3)
After attempt I came here ...I tried with pyyaml but due to nested it is not giving proper output and order is also changingTobey
@anthon has suggested to use ruamel.yaml will try using thatTobey
@mkrieger1 worked with ruamel.yaml ... My request dont be in hurry to downvote by saying not trying .....Tobey
T
8

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'))
Tobey answered 22/11, 2017 at 2:9 Comment(0)
S
8

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]
Subchloride answered 15/8, 2018 at 18:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.