将正确缩进的嵌套字典转储到yaml



我非常接近于自动转储从数据帧创建的用于自动化任务的yml文件。

我有一个结构如下的函数:

def get_all_values(nested_dictionary):
for key,value in nested_dictionary.items():
model = {
"models": [
{
"name": key,
"columns": None
}
]
}            
yield(model)
for key,value in value.items():
table = [
{
"name": key,
"tests": [            
"not_null",
"unique"            
]
}
]
yield(table)
nested_dictionary = d1
get_all_values(nested_dictionary)
data = get_all_values(nested_dictionary)
with open('data.yml', 'w') as outfile:
with redirect_stdout(outfile):
for i in data:
ruamel.yaml.round_trip_dump(i,outfile, indent=5, block_seq_indent=2)

它引用的字典作为生成器生成。字典的结构是:

{'models': [{'name': 'budgets_sales', 'columns': None}]}
[{'name': 'budget_amt', 'tests': ['not_null', 'unique']}]
[{'name': 'budget_group', 'tests': ['not_null', 'unique']}]
[{'name': 'budget_name', 'tests': ['not_null', 'unique']}]
[{'name': 'budget_pk', 'tests': ['not_null', 'unique']}]

This works "well'…但是输出如下所示:

models:
-  name: budgets_sales
columns:
-  name: budget_amt
tests:
-  not_null
-  unique
-  name: budget_group
tests:
-  not_null
-  unique
-  name: budget_name
tests:
-  not_null
-  unique

我要求字典中键的所有值都有一个额外的缩进。我不知道如何使值对键缩进。

如果正确的话,它看起来像这样:

- name: budgets_sales
columns:
-  name: budget_amt
tests:
-  not_null
-  unique
-  name: budget_group
tests:
-  not_null
-  unique
-  name: budget_name
tests:
-  not_null
-  unique
-  name: budget_pk
tests:
-  not_null
-  unique
-  name: entry_type_code
tests:
-  not_null
-  unique
-  name: institution_fk
tests:
-  not_null
-  unique

谁能提供一个方法?


感谢Anthon,这就是我最终使用的:

def get_all_values(nested_dictionary):
res = [{"version":2},{"models":None}]
for key,value in nested_dictionary.items():
seq = []
res.append([{"name": key, "columns": seq}])
# for key1, value1 in value.items():  # not using value1
for key1 in value.keys():
elem = {"name": key1, "tests": ["not_null", "unique"]}
seq.append(elem)
return res
nested_dictionary = d1
get_all_values(nested_dictionary)
data = get_all_values(nested_dictionary)

with open('data.yml', 'w') as outfile:

with redirect_stdout(outfile):

for i in data:  

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=5, sequence=5, offset=4)            
yml.dump(i,outfile)

在您所需的输出中,与密钥columns关联的值是一个序列。只有当你的Python数据结构是一个列表时,你才能得到它,所以确保你将您的table条目附加到某个变量。

我猜d1基于你的"不正确"。输出:

import sys
import ruamel.yaml
d1 = dict(budgets_sales=dict(budget_amt=None, budget_group=None, budget_name=None, budget_pk=None))
def get_all_values(nested_dictionary):
res = []
for key,value in nested_dictionary.items():
seq = []
res.append({"name": key, "columns": seq})
# for key1, value1 in value.items():  # not using value1
for key1 in value.keys():
elem = {"name": key, "tests": ["not_null", "unique"]}
seq.append(elem)
return res

data = get_all_values(d1)
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=5, sequence=5, offset=3)
yaml.dump(data, sys.stdout)

给了:

- name: budgets_sales
columns:
- name: budgets_sales
tests:
- not_null
- unique
- name: budgets_sales
tests:
- not_null
- unique
- name: budgets_sales
tests:
- not_null
- unique
- name: budgets_sales
tests:
- not_null
- unique

有几件事你应该考虑(除了更好地格式化你的代码和数据在这里):

  • round_trip_dump函数已被弃用,不要在新代码中使用
  • 至少从2007年9月起,包含YAML文档的文件的推荐扩展名是.yaml
  • 不要分多个阶段编写YAML文件,创建一个完整的数据结构并转储它。如果您希望在一个文件中包含多个YAML文档,请创建数据结构列表并使用.dump_all()方法。

如果所有这些都失败了,并且您想要生成有效的手工YAML作为输出,则加载该YAML(使用YAML(typ='safe').load())并检查您得到的Python数据结构。

最新更新