在 Python 中,原始字符串文字影响解释器如何解析您用引号引起来的字符。一旦进入内存,以原始字符串文字开始其生命的字符串与以普通字符串文字开始的字符串之间没有区别。在 Python 解释器中试试这个:
>>> raw = r"T"
>>> print(raw)
T
>>> raw
'\T'
>>> ordinary = "\T"
>>> print(ordinary)
T
>>> ordinary
'\T'
正如您可能发现的那样,jinja 不解析原始字符串文字。它确实有一个 {% raw %} 标签,但那是为了转义 jinja 语法。 escape(或e)过滤器用于 HTML 转义(例如,它将用 %20 替换空格)并且不影响 Python 字符串文字解析。
使用 {% set %} 块将执行您想要的操作,并且不会转义反斜杠:
{% macro raw_string() %}
{% set key -%}
\T
{%- endset %}
{{ log(key, True) }}
{% endmacro %}
-- dbt run-operation raw_string
-- \T
但如果你有很多键要处理,那将是乏味的(你需要为每个键使用一个 set 块,然后你必须单独定义字典,使用你在每个集合中定义的变量堵塞)。
最终,这对您来说是一个数据输入挑战。从这个角度来看,您可能只想创建一个有效的 JSON 或 YAML 字符串;最近版本的 dbt 在 jinja 上下文中包含 fromjson 和 fromyaml 方法。值得庆幸的是,YAML 可以在字典键中使用反斜杠,并且不会进行任何转义:
{% macro process() %}
{% set data -%}
\T: val
\\T: val
{%- endset %}
{% set my_dict = fromyaml(data) %}
{% for key, value in my_dict.items() %}
{{ log(key, True) }}
{% endfor %}
{% endmacro %}
-- dbt run-operation process
-- \T
-- \\T