You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible中用ID与DB组合作为combine的字典键避免重复覆盖?

问题:Ansible中构建含ID+DB组合键的字典以避免重复键覆盖

原始YAML数据结构

crdb:
  db:
    - test
  users:
    - id: 42712
      permissions:
        - level: ALL
          db: test

当前实现及存在的问题

目前使用以下代码构建字典:

- set_fact:
    db_user_permissions: "{{ db_user_permissions | default ({}) | combine({ item.key: item.value }) }}"
  loop: "{{ crdb.users | json_query('[*].{key: id, value: permissions}') }}"
  when: item.value

生成的输出示例:

{"db_user_permissions": {"42712": [{"db": "test", "level": "ALL"}], "42699": [{"db": "test", "level": "ALL"}]}}

但当存在重复ID时,字典中只会保留最后一个对应条目,因为字典的键是唯一的用户ID。

尝试过的错误写法

以下几种尝试均无法正确生成ID+DB的组合键:

  1. 错误拼接键名:
- set_fact:
    db_user_permissions: "{{ db_user_permissions | default ({}) | combine({ item.key_item.value[0].db : item.value }) }}"
  loop: "{{ crdb.users | json_query('[*].{key: id, value: permissions}') }}"
  when: item.value
  1. 错误嵌套Jinja2表达式:
- set_fact:
    db_user_permissions: "{{ db_user_permissions | default ({}) | combine({ {{ item.key }}_{{ item.value[0].db }} : item.value }) }}"
  loop: "{{ crdb.users | json_query('[*].{key: id, value: permissions}') }}"
  when: item.value
  1. 错误的字符串拼接语法:
- set_fact:
    db_user_permissions: "{{ db_user_permissions | default ({}) | combine({ item.key'_'item.value[0].db : item.value }) }}"
  loop: "{{ crdb.users | json_query('[*].{key: id, value: permissions}') }}"
  when: item.value

正确实现方式

方法1:在json_query中直接生成组合键

如果每个用户的permissions列表中只有一个数据库权限,可以直接在json_query里拼接ID和DB作为键:

- set_fact:
    db_user_permissions: "{{ db_user_permissions | default({}) | combine({ item.key: item.value }) }}"
  loop: "{{ crdb.users | json_query('[*].{key: id + \"_\" + permissions[0].db, value: permissions}') }}"
  when: item.value

这里通过id + "_" + permissions[0].db在json_query中直接生成ID_DB格式的组合键,避免重复键冲突。

方法2:处理多数据库权限场景

如果用户可能有多个数据库权限,需要将每个权限条目单独作为字典的一项,此时可以用subelements展开permissions列表:

- set_fact:
    db_user_permissions: "{{ db_user_permissions | default({}) | combine({ item_key: [item_perm] }) }}"
  loop: "{{ crdb.users | subelements('permissions') }}"
  vars:
    item_key: "{{ item.0.id }}_{{ item.1.db }}"
    item_perm: "{{ item.1 }}"

这种方式会将每个用户的每条权限单独生成一个ID_DB键,确保所有权限都被保留。

关键说明

Jinja2中字符串拼接需要用~运算符或者字符串格式化,不能直接在字典键的位置嵌套{{}},也不能用无运算符的直接拼接。上述方法通过正确的字符串拼接生成唯一键,解决了重复ID覆盖的问题。

内容的提问来源于stack exchange,提问作者CJW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:50:20