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

向Jinja宏传递单元素数组时的编译结果不符合预期问题

解决Jinja宏单元素数组解析异常问题

问题根源

你遇到的问题本质是Python语法特性导致的:('02')并不会被识别为单元素元组,它只是带括号的字符串,最终求值为'02'。当宏接收这个参数后直接拼入SQL语句,就会变成in 02,丢失了必要的括号和引号。正确的单元素元组写法应该是('02',)(注意末尾的逗号)。

解决方案

方案1:调用宏时传入正确的可迭代对象

在调用宏时,确保传递的是列表或带逗号的单元素元组:

{{ test_macro('code', ('02',)) }}
{{ test_macro('code', ['02']) }}

此时宏接收的codes参数是可迭代集合,Jinja会自动将其格式化为符合SQL规范的('02')或['02'],两种格式在SQL的IN子句中都能正常工作。

方案2:修改宏内部逻辑,兼容单个值输入

如果希望宏能自动处理单个字符串输入,无需调用方额外加逗号,可以修改宏的逻辑,统一处理单个值和集合:

{% macro test_macro(
  col_name=column_name,
  codes=list_of_codes
) %}
{# 把单个值转为单元素列表,统一后续处理逻辑 #}
{% set codes = [codes] if codes is string or not codes is iterable else codes %}
{# 转义元素中的单引号,避免SQL注入风险 #}
{% set formatted_codes = codes | map('string') | map('replace', "'", "''") | list %}
{{ log("Codes:" ~ codes, True) }}
    case
      when {{ col_name }} in ('{{ "', '".join(formatted_codes) }}') then 1
      else 0
    end
{% endmacro %}

这个修改实现了两个核心功能:

  • 自动将单个字符串或非可迭代值转为列表,确保后续处理的一致性
  • 对每个元素进行单引号转义,避免因内容含单引号导致SQL语法错误或注入风险

现在无论你传入'02'、('02')、('02',)还是['02'],宏都会输出正确的SQL:

case
      when code in ('02') then 1
      else 0
end

方案3:简化格式处理(适用于可信输入场景)

如果输入内容是完全可信的,无需考虑SQL注入,也可以用更简洁的写法:

{% macro test_macro(
  col_name=column_name,
  codes=list_of_codes
) %}
{% set codes = [codes] if codes is string else codes %}
{{ log("Codes:" ~ codes, True) }}
    case
      when {{ col_name }} in ({{ codes | map('string') | map('quote') | join(', ') }}) then 1
      else 0
    end
{% endmacro %}

这里用quote过滤器直接给每个元素添加单引号,再通过join拼接,效果和方案2一致,但省略了单引号转义步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:17:34