尝试使用 json 和 json_query 过滤器时模板化字符串时出现模板错误
Getting template error while templating string when trying to work with json and json_query filter
我尝试执行这个 ansible 命令:
ansible localhost -m debug -a "var={{ db_config| to_json |json_query(*)}}" \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
使用 json_query(*) 获取所有 json 元素
但我收到以下错误:
fatal: [localhost]: FAILED! =>
msg: 'template error while templating string: expected token ''end of print statement'', got ''name''. String: {{"[{\"name\":\"mydb1\",\"services\":[\"app1\",\"app2\"]},{\"name\":\"mydb12\",\"services\":[\"app1\"]}]"}}'
这个单行有几个问题:
- 在您的情况下用于调试的参数是
msg
(输出模板或静态值的结果)而不是 var
(用于调试单个变量而不进行任何转换) .请参阅 debug module documentation
- 您正在将 json 字符串表示形式作为参数传递。您要使用的过滤器是
from_json
(将您的字符串转换为 dict/list)而不是 to_json
(恰恰相反)。
- 您在
json_query
中的 jmespath expression 无效,原因有二:
- 这不是一个字符串(只是一个简单的通配符)
- 即使引用也不符合规范(按照上面的link)。
下面固定的一个衬里给出了你期望的结果(我相信......):
$ ansible localhost -m debug -a 'msg={{ db_config | from_json | json_query("[]") }}' \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
localhost | SUCCESS => {
"msg": [
{
"name": "mydb1",
"services": [
"app1",
"app2"
]
},
{
"name": "mydb12",
"services": [
"app1"
]
}
]
}
请注意,您甚至可以通过将您的论点作为完整内联 json:
传递来放弃 json 解码步骤
$ ansible localhost -m debug -a 'msg={{ db_config | json_query("[]") }}' \
-e '{"db_config":[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]}'
localhost | SUCCESS => {
"msg": [
{
"name": "mydb1",
"services": [
"app1",
"app2"
]
},
{
"name": "mydb12",
"services": [
"app1"
]
}
]
}
我怀疑您正在尝试所有这些以稍后测试 json_query
表达式以 select 您的数据。
- 你应该知道ansible中还有很多其他核心过滤器(其中
selectattr
、rejectattr
、select
、reject
、map
, dict2items
, items2dict
, first
, last
, unique
, zip
, subelements
,...)组合在一起可以完成大部分工作 json_query
可以在没有开销的情况下完成(安装 python 模块和 ansible 集合)。 json_query
只有非常复杂的查询才真正需要。
- 万一我错了,你的最终目标真的是显示输入数据的所有元素,你可以过度简化。来自以上两个例子:
$ ansible localhost -m debug -a 'msg={{ db_config | from_json }}' \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
# OR (the next one can work with `var` for debug)
$ ansible localhost -m debug -a 'var=db_config' \
-e '{"db_config":[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]}'
如果将数据放入文件
shell> cat test-data.yml
---
db_config:
- {name: "mydb1", services: ["app1", "app2"]}
- {name: "mydb12", services: ["app1"]}
如果您将代码放入剧本
shell> cat test.yml
---
- hosts: localhost
tasks:
- debug:
msg: "{{ db_config|json_query('[]') }}"
该命令按预期工作
shell> ansible-playbook test.yml -e @test-data.yml
...
msg:
- name: mydb1
services:
- app1
- app2
- name: mydb12
services:
- app1
我尝试执行这个 ansible 命令:
ansible localhost -m debug -a "var={{ db_config| to_json |json_query(*)}}" \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
使用 json_query(*) 获取所有 json 元素 但我收到以下错误:
fatal: [localhost]: FAILED! =>
msg: 'template error while templating string: expected token ''end of print statement'', got ''name''. String: {{"[{\"name\":\"mydb1\",\"services\":[\"app1\",\"app2\"]},{\"name\":\"mydb12\",\"services\":[\"app1\"]}]"}}'
这个单行有几个问题:
- 在您的情况下用于调试的参数是
msg
(输出模板或静态值的结果)而不是var
(用于调试单个变量而不进行任何转换) .请参阅 debug module documentation - 您正在将 json 字符串表示形式作为参数传递。您要使用的过滤器是
from_json
(将您的字符串转换为 dict/list)而不是to_json
(恰恰相反)。 - 您在
json_query
中的 jmespath expression 无效,原因有二:- 这不是一个字符串(只是一个简单的通配符)
- 即使引用也不符合规范(按照上面的link)。
下面固定的一个衬里给出了你期望的结果(我相信......):
$ ansible localhost -m debug -a 'msg={{ db_config | from_json | json_query("[]") }}' \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
localhost | SUCCESS => {
"msg": [
{
"name": "mydb1",
"services": [
"app1",
"app2"
]
},
{
"name": "mydb12",
"services": [
"app1"
]
}
]
}
请注意,您甚至可以通过将您的论点作为完整内联 json:
传递来放弃 json 解码步骤$ ansible localhost -m debug -a 'msg={{ db_config | json_query("[]") }}' \
-e '{"db_config":[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]}'
localhost | SUCCESS => {
"msg": [
{
"name": "mydb1",
"services": [
"app1",
"app2"
]
},
{
"name": "mydb12",
"services": [
"app1"
]
}
]
}
我怀疑您正在尝试所有这些以稍后测试 json_query
表达式以 select 您的数据。
- 你应该知道ansible中还有很多其他核心过滤器(其中
selectattr
、rejectattr
、select
、reject
、map
,dict2items
,items2dict
,first
,last
,unique
,zip
,subelements
,...)组合在一起可以完成大部分工作json_query
可以在没有开销的情况下完成(安装 python 模块和 ansible 集合)。json_query
只有非常复杂的查询才真正需要。 - 万一我错了,你的最终目标真的是显示输入数据的所有元素,你可以过度简化。来自以上两个例子:
$ ansible localhost -m debug -a 'msg={{ db_config | from_json }}' \
-e 'db_config=[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]'
# OR (the next one can work with `var` for debug)
$ ansible localhost -m debug -a 'var=db_config' \
-e '{"db_config":[{"name":"mydb1","services":["app1","app2"]},{"name":"mydb12","services":["app1"]}]}'
如果将数据放入文件
shell> cat test-data.yml
---
db_config:
- {name: "mydb1", services: ["app1", "app2"]}
- {name: "mydb12", services: ["app1"]}
如果您将代码放入剧本
shell> cat test.yml
---
- hosts: localhost
tasks:
- debug:
msg: "{{ db_config|json_query('[]') }}"
该命令按预期工作
shell> ansible-playbook test.yml -e @test-data.yml
...
msg:
- name: mydb1
services:
- app1
- app2
- name: mydb12
services:
- app1