我使用Ansible模板将变量包含在SQL导入文件中,直到最近一切都很好,Ansible现在正在分析模板中变量周围的引号,并删除其中一些,而以前从未这样做过。
例如,以下。。。
INSERT INTO `my_table` VALUES (1, '{{ var.one }}', NULL, '{{ var.two }}');
现在导致…
INSERT INTO `my_table` VALUES (1, 'value-one, NULL, value-two');
请注意,中间的两个单引号已被删除。这会破坏SQL。根据MySQL/ANSI标准,我应该对字符串文字使用单引号,而只对标识符使用反引号。那么这里的解决方案是什么呢?有人知道这种行为是什么时候改变的吗?
我正在使用Ansible 2.9.27
根据请求,这里是简单的模板任务调用。。。
- name: Copy SQL Dynamic Data Dump File for import
template: src=data.sql.j2 dest=/tmp/data.sql
这个问题已经解决。下面的例子适用于2.10和2.12
- ansible[core 2.12.1],python 3.8.5,jinja 3.0.1
- ansible 2.10.11,python 3.6.9,python3-jinja2 2.10-1ubuntu10.18.04.1
shell> cat import.sql.j2
INSERT INTO my_table VALUES (1, '{{ var.one }}', NULL, '{{ var.two }}');
和任务
- template:
src: import.sql.j2
dest: import.sql
vars:
var:
one: value-one
two: value-two
提供有效的SQL
shell> cat import.sql
INSERT INTO my_table VALUES (1, 'value-one', NULL, 'value-two');
作为一种变通方法,将单引号放入表达式中
shell> cat import.sql.j2
INSERT INTO my_table VALUES (1, {{ "'" }}{{ var.one }}{{ "'" }}, NULL, {{ "'" }}{{ var.two }}{{ "'" }});
使用sed在全局范围内进行这些更改,例如
shell> cat templates/import.sql.j2
INSERT INTO my_table VALUES (1, '{{ var.one }}', NULL, '{{ var.two }}');
shell> for i in templates/*; do sed -i "s/'/{{ "'" }}/g" $i; done
shell> cat templates/import.sql.j2
INSERT INTO my_table VALUES (1, {{ "'" }}{{ var.one }}{{ "'" }}, NULL, {{ "'" }}{{ var.two }}{{ "'" }});
(可选(选择一个linter并验证SQL。模板模块中的验证选项不适用于sqlfluff,因此下面使用下一个命令任务。线路长度的测试被排除(--排除规则L016(。
- template:
src: import.sql.j2
dest: import.sql
register: result
vars:
var:
one: value-one
two: value-two
- command: "sqlfluff lint {{ result.dest }} --exclude-rules L016"
changed_when: false
很明显,这与在2.11中修复的Jinja2中的一个已知错误有关。不过我使用的是3.0.3,所以奇怪的是它仍然是一个问题,所以我用Ansible发布了一个错误报告,他们已经确认了这种行为。Jinja2 Native在模板中的使用方式在Ansible 2.11中发生了变化,这应该会缓解这个问题,然而,在我们发行版的发布通道中提供之前,我们已经能够通过禁用";"本地";我们正在使用的Jinja2的支持。这可能会导致其他问题,但我们陷入了困境,因为Ansible 2.9现在只收到安全补丁。
我的Bug报告如下:https://github.com/ansible/ansible/issues/76761
Jinja2 Bug报告如下:https://github.com/pallets/jinja/issues/1020