web-dev-qa-db-ja.com

YAMLファイルにデータを追加する方法

以下の内容のファイル_*.yaml_があります。

_bugs_tree:
  bug_1:
    html_Arch: filepath
    moved_by: user1
    moved_date: '2018-01-30'
    sfx_id: '1'
_

ノードの下のこのファイルに新しい子要素を追加したい_[bugs_tree]_以下のようにしてみました:

_if __name__ == "__main__":
    new_yaml_data_dict = {
        'bug_2': {
            'sfx_id': '2', 
            'moved_by': 'user2', 
            'moved_date': '2018-01-30', 
            'html_Arch': 'filepath'
        }
    }

    with open('bugs.yaml','r') as yamlfile:
        cur_yaml = yaml.load(yamlfile)
        cur_yaml.extend(new_yaml_data_dict)
        print(cur_yaml)
_

次に、ファイルは次のようになります。

_bugs_tree:
  bug_1:
    html_Arch: filepath
    moved_by: username
    moved_date: '2018-01-30'
    sfx_id: '1234'
  bug_2:
    html_Arch: filepath
    moved_by: user2
    moved_date: '2018-01-30'
    sfx_id: '2'
_

.append() OR .extend() OR .insert()を実行しようとすると、エラー

_cur_yaml.extend(new_yaml_data_dict)
AttributeError: 'dict' object has no attribute 'extend'
_
5
Qex

update を使用する必要があります

cur_yaml.update(new_yaml_data_dict)

結果のコード

with open('bugs.yaml','r') as yamlfile:
        cur_yaml = yaml.load(yamlfile)
        cur_yaml.update(new_yaml_data_dict)
        print(cur_yaml)

with open('bugs.yaml','w') as yamlfile:
        yaml.safe_dump(cur_yaml, yamlfile) # Also note the safe_dump
3
Arpit Solanki

ファイルを更新する場合は、読み取りだけでは不十分です。また、ファイルに対して再度書き込む必要があります。このような何かがうまくいくでしょう:

with open('bugs.yaml','r') as yamlfile:
    cur_yaml = yaml.safe_load(yamlfile) # Note the safe_load
    cur_yaml['bugs_tree'].update(new_yaml_data_dict)

if cur_yaml:
    with open('bugs.yaml','w') as yamlfile:
        yaml.safe_dump(cur_yaml, yamlfile) # Also note the safe_dump

私はこれをテストしませんでしたが、彼の考えは、readtoreadファイルとwritetowriteto the file。使用する safe_loadおよびsafe_dumpのように Anthon が言った:

「安全でないと記載されているload()を使用する必要はまったくありません。代わりにsafe_load()を使用してください。」

3
Nebulosar

これが全員のユースケースに適合するかどうかはわかりませんが、私はあなたができることを見つけます...ファイルに追加しますトップレベルのリストを保持している場合のみ

これを行う1つの動機は、それが理にかなっているということです。もう1つは、毎回yamlファイル全体を再読み込みして解析する必要があるかどうかについて私が懐疑的であるということです。私がやりたかったことは、Djangoミドルウェアを使用して着信リクエストをログに記録し、開発中の複数のページの読み込みで発生していたバグをデバッグすることでした。これはかなり時間的に重要です。

OPが望むことをする必要がある場合は、バグを独自のファイルに残して、そこからbugs_treeのコンテンツを作成することを検討します。

import os
import yaml
def write(new_yaml_data_dict):

    if not os.path.isfile("bugs.yaml"):

        with open("bugs.yaml", "a") as fo:
            fo.write("---\n")

    #the leading spaces and indent=4 are key here!
    sdump = "  " + yaml.dump(
                new_yaml_data_dict
                ,indent=4
                )

    with open("bugs.yaml", "a") as fo:
        fo.write(sdump)

new_yaml_data_dict = {
        'bug_1': {
            'sfx_id': '1', 
            'moved_by': 'user2', 
            'moved_date': '2018-01-20', 
            'html_Arch': 'filepath'
        }
    }
write(new_yaml_data_dict)
new_yaml_data_dict = {
        'bug_2': {
            'sfx_id': '2', 
            'moved_by': 'user2', 
            'moved_date': '2018-01-30', 
            'html_Arch': 'filepath'
        }
    }
write(new_yaml_data_dict)

その結果

---
  bug_1:
    html_Arch: filepath
    moved_by: user2
    moved_date: '2018-01-20'
    sfx_id: '1'
  bug_2:
    html_Arch: filepath
    moved_by: user2
    moved_date: '2018-01-30'
    sfx_id: '2'
0
JL Peyret