Добавить дублирующую пару значений ключа во вложенный словарь в YAML - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь добавить дубликат пары ключ: значение во вложенный словарь в файле YAML с помощью скрипта Python. Ниже приведен фрагмент кода, который я написал для достижения этой цели:

import click
import ruamel.yaml

def organization():
    org_num = int(input("Please enter the number of organizations to be created: "))
    org_val = 0
    while org_val!= org_num:
        print ("")
        print("Please enter values to create Organizations")
        print ("")
        for org in range(org_num):
            organization.org_name = str(raw_input("Enter the Organization Name: "))
            organization.org_description = str(raw_input("Enter the Description of Organization: "))
            print ("")
            if click.confirm("Organization Name: "+ organization.org_name + "\nDescription: "+ organization.org_description + "\nIs this Correct?", default=True):
                if org_val == 0:
                    org_val = org_val + 1
                    yaml = ruamel.yaml.YAML()
                    org_data = dict(
                        organizations=dict(
                            name=organization.org_name,
                            description=organization.org_description,
                        )
                    )
                    with open('input.yml', 'a') as outfile:
                        yaml.indent(mapping=2, sequence=4, offset=2)
                        yaml.dump(org_data, outfile)

               else:
                   org_val = org_val + 1
                   yaml = ruamel.yaml.YAML()
                   org_data = dict(
                            name=organization.org_name,
                            description=organization.org_description,
                            )
                   with open('input.yml', 'r') as yamlfile:
                       cur_yaml = yaml.load(yamlfile)
                       cur_yaml['organizations'].update(org_data)

                   if cur_yaml:
                       with open('input.yml','w') as yamlfile:
                           yaml.indent(mapping=2, sequence=4, offset=2)
                           yaml.dump(cur_yaml, yamlfile)
    return organization.org_name, organization.org_description

organization()

В конце скрипта Python мой input.yml файл должен выглядеть следующим образом:

version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations:
  -  description: xyz
     name: abc
  -  description: pqr
     name: def

Однако каждый раз, когда скрипт выполняется, вместо добавления значения в организации он перезаписывает его.

Я также пытался использовать append вместо update, но я получаю следующую ошибку:

AttributeError: у объекта 'CommentedMap' нет атрибута 'append'

Что я могу сделать, чтобы решить эту проблему?

Кроме того, поскольку я новичок в разработке, любые предложения по улучшению этого кода будут действительно полезны.

Ответы [ 3 ]

0 голосов
/ 06 сентября 2018

Использование update не сработает, потому что значение для ключа organizations является последовательностью и загружается как list -подобный тип CommentedSeq. Так что append -ing будет правильным решением.

То, что это не работает, немного неясно, так как вы не предоставляете этот ввод что вы начинаете, ни код, используемый при выполнении append, который получает AttributeError на CommentedMap.

Вот что работает, если у вас есть одна организация и добавлена ​​другая:

import sys
import ruamel.yaml

yaml_str = """\
version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations:
  -  description: xyz
     name: abc
"""

org_data = dict(
   description='pqr',
   name='def',
)

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4, sequence=4, offset=2)

cur_yaml = yaml.load(yaml_str)
cur_yaml['organizations'].append(org_data)
yaml.dump(cur_yaml, sys.stdout)

Это дает:

version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations:
  - description: xyz
    name: abc
  - description: pqr
    name: def

Если у вас еще нет организаций, убедитесь, что ваш ввод YAML выглядит следующим образом:

version: x.x.x
is_enterprise: 'true'
license: secrets/license.txt
organizations: []

В старых версиях Python порядок ключей в добавленных вами данных не гарантируется. к Примените этот порядок и к более старой версии:

org_data = ruamel.yaml.comments.CommentedMap((('description', 'pqr'), ('name', 'def')))

или

org_data = ruamel.yaml.comments.CommentedMap()
org_data['description'] = 'pqr'
org_data['name'] = 'def'
0 голосов
/ 06 сентября 2018

Найдена проблема и теперь она работает нормально. Поскольку имя и описание являются списочными объектами для организаций, я добавил [] в приведенный ниже код, и он начал работать.

org_data = dict(
    organizations=[dict(
        name=tower_organization.org_name,
        description=tower_organization.org_description,
    )
    ]
)

В дополнение к вышесказанному, я полагаю, что append не работал из-за дефиса '-', который отсутствовал в первом объекте как часть идентификации. После исправления приведенного выше кода приложение append также работает нормально.

Спасибо всем за ваши ответы.

0 голосов
/ 06 сентября 2018

Если я правильно понимаю, вы хотите cur_yaml['organizations'] += [org_data].

Обратите внимание, что если вы запустите скрипт много раз, у вас будет одна и та же запись несколько раз.

...