Ansible遍历多CSV文件元素报错:list对象无prefix属性
问题分析与解决方案
问题背景
现有Ansible Playbook需要处理多个CSV文件,目录结构如下:
/tmp/test/foo csv1/ sample.csv csv2/ sample.csv
执行命令:
ansible-playbook playbook.yaml -e "csv=csv1,csv2"
修改后的Playbook尝试读取多个CSV并处理每行的prefix字段(按:拆分),但执行时出现错误:
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'prefix'
错误原因
核心问题是vms.results | json_query('[].list')返回的是嵌套列表结构:每个CSV文件对应一个子列表,子列表里是该行的对象。比如结构类似:
[ [{"table_name": "t1", "column_name": "c1", "prefix": "p1:p2"}, ...], [{"table_name": "t2", "column_name": "c2", "prefix": "p3:p4"}, ...] ]
直接对这个结构做loop时,item会是每个子列表(而非单个CSV行对象),子列表自然没有prefix属性,因此触发错误。
修正后的Playbook
需要先将嵌套列表扁平化,直接获取所有CSV行的扁平列表,修改后的Playbook如下:
- hosts: localhost tasks: - name: Read CSV files read_csv: path: "/tmp/test/foo/{{ item }}/sample.csv" with_items: "{{ csv.split(',') }}" register: vms - name: Debug flattened CSV rows debug: msg: "{{ item }}" loop: "{{ vms.results | json_query('[].list[]') }}" # 用[]展开所有子列表元素 - name: Compute prefixes to perform combination set_fact: vms_data: "{{ vms_data | default([]) + [item | combine({'prefix': item.prefix.split(':')})] }}" loop: "{{ vms.results | json_query('[].list[]') }}" # 同样用扁平化后的列表 - debug: msg: "{{ vms_data }}" - name: Run shell command for each prefix debug: msg: "Running shell command for table -> {{ item.0.table_name }} in column -> {{ item.0.column_name }} for prefix -> {{ item.1 }}" loop: "{{ vms_data | subelements('prefix') }}"
关键修正点
- 将
json_query('[].list')改为json_query('[].list[]'):后者会遍历每个list下的所有元素,直接返回所有CSV行对象的扁平列表,而非嵌套列表。 - 也可以用
flatten(1)替代JSON query的调整:loop: "{{ vms.results | json_query('[].list') | flatten(1) }}",效果完全一致。
内容的提问来源于stack exchange,提问作者Jninja
相关产品推荐
相关产品推荐

