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

如何从Helm Helper函数返回列表变量并实现模板迭代?

问题:Helm模板Helper函数如何返回列表供遍历?

在Helm模板中,为了减少重复代码,需要合并values.yaml中的两个字段:单个对象schema和对象列表schemas,统一成一个列表后遍历。原本的合并逻辑如下:

{{- $schemas := list -}}
{{- if .Values.schema -}}
{{- $schemas = list .Values.schema -}}
{{- end -}}
{{- if .Values.schemas -}}
{{- $schemas = .Values.schemas -}}
{{- end -}}

为了避免在多个模板中复制这段代码,将其封装成Helper函数:

{{- define "helper.schemas" -}}
{{- $schemas := list -}}
{{- if .Values.postgres.database.schema -}}
{{- $schemas = list .Values.postgres.database.schema -}}
{{- end -}}
{{- if .Values.postgres.database.schemas -}}
{{- $schemas = .Values.postgres.database.schemas -}}
{{- end -}}
{{- $schemas }}
{{- end -}}

但在主模板中调用时:

{{- range $indx, $schema := include "helper.schemas" .  }}
...
{{- end }}

出现错误:range can't iterate over [map[.. ..]]。


解决方案

问题根源

include函数会将Helper模板的输出转换成字符串,而非直接返回Go模板的变量(列表/映射类型)。因此range尝试遍历字符串而非真正的列表,导致报错。

可行解决方法

方法1:使用tpl函数解析Helper输出

tpl函数可将字符串形式的YAML/模板解析为Helm能识别的变量类型。修改主模板的调用方式:

{{- /* 用tpl解析Helper返回的字符串为列表 */ -}}
{{- range $indx, $schema := tpl (include "helper.schemas" .) . }}
# 这里编写遍历逻辑
{{- end }}

注意:Helper中输出的$schemas必须是合法的YAML格式,确保tpl能正确解析。

方法2:合并逻辑与渲染逻辑分离(推荐)

更清晰的做法是先在主模板中完成列表合并,再调用Helper渲染单个列表项:

  1. 定义渲染单个schema的Helper:
{{- define "helper.schema.render" -}}
# 单个schema的渲染逻辑示例
apiVersion: v1
kind: ConfigMap
metadata:
  name: schema-{{ .name }}
data:
  schema.sql: |
    {{ .sqlContent }}
{{- end }}
  1. 在主模板中合并列表并遍历:
{{- /* 合并schema和schemas为统一列表 */ -}}
{{- $schemas := list -}}
{{- if .Values.postgres.database.schema -}}
{{- $schemas = append $schemas .Values.postgres.database.schema -}}
{{- end -}}
{{- if .Values.postgres.database.schemas -}}
{{- $schemas = concat $schemas .Values.postgres.database.schemas -}}
{{- end -}}

{{- /* 遍历列表,调用Helper渲染每个项 */ -}}
{{- range $indx, $schema := $schemas }}
{{ include "helper.schema.render" $schema }}
{{- end }}

注:若需求是优先使用schemas列表(存在时忽略单个schema),可将合并逻辑改回原来的覆盖方式,而非append/concat。

方法3:通过上下文传递变量

在Helper中将合并后的列表存入当前上下文,供主模板直接使用:

  1. 定义初始化Helper:
{{- define "helper.schemas.init" -}}
{{- $schemas := list -}}
{{- if .Values.postgres.database.schema -}}
{{- $schemas = list .Values.postgres.database.schema -}}
{{- end -}}
{{- if .Values.postgres.database.schemas -}}
{{- $schemas = .Values.postgres.database.schemas -}}
{{- end -}}
{{- /* 将合并后的列表存入上下文的schemas字段 */ -}}
{{- $_ := set . "schemas" $schemas -}}
{{- end -}}
  1. 在主模板中调用Helper并遍历:
{{- /* 先初始化上下文里的schemas变量 */ -}}
{{- include "helper.schemas.init" . -}}
{{- /* 直接遍历上下文里的schemas */ -}}
{{- range $indx, $schema := .schemas }}
# 编写遍历逻辑
{{- end }}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:11:19