Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
469 views
in Technique[技术] by (71.8m points)

How do I update this yaml file with python and ruamel?

I have a test.yaml file with content:

school_ids:
  school1: "001"

  #important school2
  school2: "002"


targets:
  neighborhood1:
    schools:
      - school1-paloalto
    teachers:
      - 33
  neighborhood2:
    schools:
      - school2-paloalto
    teachers:
      - 35

I want to use ruamel to update the file to look like this:

school_ids:
  school1: "001"

  #important school2
  school2: "002"

  school3: "003"


targets:
  neighborhood1:
    schools:
      - school1-paloalto
    teachers:
      - 33
  neighborhood2:
    schools:
      - school2-paloalto
    teachers:
      - 35
  neighborhood3:
    schools:
      - school3-paloalto
    teachers:
      - 31

How do I use ruamel to update the file to get the desired output by preserving the comments?

Here's what I have so far:

import sys
from ruamel.yaml import YAML

inp = open('/targets.yaml', 'r').read()

yaml = YAML()

code = yaml.load(inp)
account_ids = code['school_ids']
account_ids['new_school'] = "003"
#yaml.dump(account_ids, sys.stdout)


targets = code['targets']
new_target = dict(neighborhood3=dict(schools=["school3-paloalto"], teachers=["31"]))
yaml = YAML()
yaml.indent(mapping=2, sequence=3, offset=2)
yaml.dump(new_target, sys.stdout)
question from:https://stackoverflow.com/questions/65946240/how-do-i-update-this-yaml-file-with-python-and-ruamel

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are just dumping new_target which you create from scratch not using the code or even targets. Instead you should either use that code that you loaded and extend the values associated with its root level keys and then dump code:

import sys
from pathlib import Path
from ruamel.yaml import YAML

inp = Path('test.yaml')

yaml = YAML()

code = yaml.load(inp)
school_ids = code['school_ids']
school_ids['school3'] = "003"


targets = code['targets']
targets['neighborhood3'] = dict(schools=["school3-paloalto"], teachers=["31"])
yaml = YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.dump(code, sys.stdout)

which gives:

school_ids:
  school1: '001'

  #important school2
  school2: '002'


  school3: '003'
targets:
  neighborhood1:
    schools:
      - school1-paloalto
    teachers:
      - 33
  neighborhood2:
    schools:
      - school2-paloalto
    teachers:
      - 35
  neighborhood3:
    schools:
      - school3-paloalto
    teachers:
      - '31'

Please note that your sequence indent needs to be at least 2 greater than your offset (2 positions to have room for - + SPACE)

The output has the emtpy lines between after the key school2, as that is what these are associated with during parsing. This can be moved to the new key, but it is not trivial. If you need to do that (it is not important for the semantics of the YAML document), then have a look at my answer here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...