Python 在ansible中合并字典

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25422771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:12:16  来源:igfitidea点击:

merging dictionaries in ansible

pythondictionarymergeansible

提问by Berry Langerak

I'm currently building a role for installing PHP using ansible, and I'm having some difficulty merging dictionaries. I've tried several ways to do so, but I can't get it to work like I want it to:

我目前正在构建一个使用 ansible 安装 PHP 的角色,但我在合并词典时遇到了一些困难。我已经尝试了几种方法来做到这一点,但我无法让它像我想要的那样工作:

# A vars file:
my_default_values:
  key = value

my_values:
  my_key = my_value


# In a playbook, I create a task to attempt merging the
# two dictionaries (which doesn't work):

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: my_default_values + my_values

# I have also tried:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: my_default_values|union(my_values)

# I have /some/ success with using j2's update,
# but you can't use j2 syntax in "with_dict", it appears.
# This works:

- debug: msg="{{ my_default_values.update(my_values) }}"

# But this doesn't:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: my_default_values.update(my_values)

Is there a way to merge two dictionaries, so I can use it with "with_dict"?

有没有办法合并两个字典,以便我可以将它与“with_dict”一起使用?

采纳答案by augurar

In Ansible 2.0, there is a Jinja filter, combine, for this:

在 Ansible 2.0 中,有一个 Jinja 过滤器combine,用于:

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: "{{ my_default_values | combine(my_values) }}"

回答by Quentin THEURET

>>> key = 'default key'
>>> value = 'default value'
>>> my_key = 'my key'
>>> my_value = 'my value'
>>>
>>> my_default_values = {key: value}
>>> print my_default_values
{'default key': 'default value'}
>>>
>>> my_values = {my_key: my_value}
>>> print my_values
{'my key': 'my value'}
>>>
>>> with_dict = my_default_value.copy()
>>> print with_dict
{'default key': 'default value'}
>>> with_dict.update(my_values)
>>> print with_dict
{'default key': 'default value', 'my key': 'my value'}

回答by jarv

If you want hash merging I would turn the hash merging feature on in ansible. In your ansible config file turn hash merging on.

如果你想要哈希合并,我会在 ansible 中打开哈希合并功能。在您的 ansible 配置文件中,打开哈希合并

With hash_behaviour=mergeyou can have two var files with the same variable name:

使用hash_behaviour=merge你可以有两个变量名相同的 var 文件:

defaults.yml:

默认值.yml:

values:
  key: value

overrides.yml:

覆盖.yml:

values:
  my_key: my_value

In order for the two vars to be merged you will need to include both var files:

为了合并两个变量,您需要包含两个变量文件:

ansible-playbook some-play.yml ... [email protected]  [email protected]

And you will end up with this:

你最终会得到这个:

TASK: [debug var=values] ********************************************************
ok: [localhost] => {
    "values": {
        "key": value,
        "my_key": my_value
    }
}

Calling update on a variable can be done in Jinja but in general it will be messy, I wouldn't do it outside of your templates and even then try to avoid it altogether.

可以在 Jinja 中调用更新变量,但一般来说它会很混乱,我不会在你的模板之外这样做,即使那样也尽量避免它。

回答by Nat

If you need the merged dictionary a few times, you can set it to a new "variable":

如果多次需要合并字典,可以将其设置为新的“变量”:

- set_fact: _my_values="{{?my_default_values|combine(my_values) }}"

- debug: msg="{{ item.key }} = {{ item.value }}"
  with_dict: _my_values

回答by eugene0707

Try this rolefrom Ansible Galaxy.

试试这个来自 Ansible Galaxy 的角色

I did it some time ago for same reason. It can deep merge dictionaries from several vars files and set custom precedence of merging.

前段时间我也出于同样的原因这样做了。它可以从多个 vars 文件中深度合并字典并设置合并的自定义优先级。

This role can work under Ansible 2.0+

这个角色可以在 Ansible 2.0+ 下工作

回答by leiiv

It is now possible to use the anchor and extend features of YAML:

现在可以使用 YAML 的锚点和扩展功能:

---
- hosts: localhost
  vars:
    my_default_values: &def
      key: value
    my_values:
      <<: *def
      my_key: my_value
  tasks:
    - debug: var=my_default_values
    - debug: var=my_values

Result:

结果:

TASK [debug]
ok: [localhost] => {
    "my_default_values": {
        "key": "value"
    }
}

TASK [debug] 
ok: [localhost] => {
    "my_values": {
        "key": "value", 
        "my_key": "my_value"
    }
}

I have no idea why this was not mentioned before.

我不知道为什么之前没有提到这一点。