I have small python script which responsible for updating my yaml file by adding new records:
data = yaml.load(file)
data['WIN']['Machine'] = dict(node_labels='+> tfs vs2022')
data['WIN']['Machine'] = dict(vs='vs2022')
yaml.dump(data, file)
Every time when I run above script I will get updated yaml file like below:
WIN:
Machine:
vs: vs2022
My desired output to have both my key: value pairs
WIN:
Machine:
node_labels: +> tfs vs2022
vs: vs2022
I'm wondering why line data['WIN'][nodeName] = dict(node_labels='+> tfs vs2022')
overwritten by next line? How can add several key: values for Machine
section?
This is not a YAML related problem, but a conceptual problem in your non-yaml related Python code.
By assigning a dict as value to the key Machine
, you set that value. By assigning another dict to the key, you overwrite that value completely, erasing the previous key-value pair.
If you simplify your code:
data = dict(Machine=None)
data['Machine'] = dict(node_labels='+> tfs vs2022')
print('data 1', data)
data['Machine'] = dict(vs='vs2022')
print('data 2', data)
As you can see after the second assignment, the key node_labels
is no longer available.
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'vs': 'vs2022'}}
There are several ways to solve this. You can either assign a value to a key in the first dict:
data = dict(Machine=None)
data['Machine'] = added_dict = dict(node_labels='+> tfs vs2022')
print('data 1', data)
added_dict['vs'] ='vs2022'
print('data 2', data)
Now you have both keys in the second output:
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'node_labels': '+> tfs vs2022', 'vs': 'vs2022'}}
If you don't already know there is a dict where you can add a key to, you might to use .setdefault
, either using key-value assigment, and/or by using .update
(useful for updating multiple keys in one go):
data = dict()
data.setdefault('Machine', {})['node_labels'] = '+> tfs vs2022'
print('data 1', data)
data.setdefault('Machine', {}).update(dict(vs='vs2022'))
print('data 2', data)
data 1 {'Machine': {'node_labels': '+> tfs vs2022'}}
data 2 {'Machine': {'node_labels': '+> tfs vs2022', 'vs': 'vs2022'}}
Of course you can put node_labels
and vs
in one dict and assign, but that would overwrite any existing key-values loaded from YAML. So the use of .update
is IMO better:
import sys
from pathlib import Path
import ruamel.yaml
file_in = Path('input.yaml')
# key in YAML mapping with null value
file_in.write_text("""\
WIN:
""")
yaml = ruamel.yaml.YAML()
data = yaml.load(file_in)
if data['WIN'] is None:
data['WIN'] = {}
data['WIN'].setdefault('Machine', {}).update(dict(node_labels='+> tfs vs2022'))
data['WIN'].setdefault('Machine', {}).update(dict(vs='vs2022'))
yaml.dump(data, sys.stdout)
which gives your expected result:
WIN:
Machine:
node_labels: +> tfs vs2022
vs: vs2022
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.