渲染Jinja模板时如何使用存储字典值的外部文件作为数据源
实现方案
你提供的原始代码末尾存在重复粘贴的冗余任务配置片段,会触发语法错误,先清理基础结构后按以下步骤改造即可:
第一步:准备外部数据源文件
推荐用JSON或YAML格式存储结构化的账号字典数据,按需选择即可:
- 选JSON(Python原生支持,无需额外依赖):在项目根目录新建
accounts.json,写入原硬编码的列表内容:
[ {"alias": "MEMBER1", "region": "us-east-1", "member_account_id": "0000000000", "ccs_mem_account_id": "0000000000"}, {"alias": "MEMBER2", "region": "us-east-2", "member_account_id": "0000000000", "ccs_mem_account_id": "0000000000"} ]
- 选YAML(手写可读性更强):先执行
pip install pyyaml安装依赖,在项目根目录新建accounts.yaml:
- alias: MEMBER1 region: us-east-1 member_account_id: '0000000000' ccs_mem_account_id: '0000000000' - alias: MEMBER2 region: us-east-2 member_account_id: '0000000000' ccs_mem_account_id: '0000000000'
注意:账号ID是数字开头的长字符串,YAML中必须加引号包裹,否则会被解析为数字类型丢失精度
第二步:改造代码适配外部数据源+doit增量构建逻辑
doit通过file_dep列表中的文件哈希判断是否需要重跑任务,必须把数据源文件加入依赖列表,否则修改账号配置后不会自动触发重新渲染。完整改造后代码如下:
from jinja2 import Environment, FileSystemLoader from pathlib import Path import json # 选用YAML时放开下方导入 # import yaml # 统一配置数据源文件路径 DATA_SOURCE_PATH = Path("accounts.json") # 选用YAML时替换为下方路径 # DATA_SOURCE_PATH = Path("accounts.yaml") def load_account_data(): """从外部文件加载最新的账号配置数据""" with open(DATA_SOURCE_PATH, "r", encoding="utf-8") as f: # JSON格式用该行加载 return json.load(f) # YAML格式替换为下方行 # return yaml.safe_load(f) def task_render(): """Render jinja2 templates. Yields: Render task for each jinja2 template file. """ cwd = Path(".") environment = Environment(loader=FileSystemLoader(cwd, encoding="utf-8")) j2_templates = cwd.glob("*.j2") def render_template(template_path): """Render template. Args: template_path: Path to jinja2 template file """ # 每次渲染前实时加载最新数据,避免缓存旧配置 account_details = load_account_data() template = environment.get_template(str(template_path)) with open(f"{template_path.stem}", "w", encoding="utf-8") as output_file: output_file.write(template.render(data=account_details)) for j2_template in j2_templates: target = f"_{j2_template.stem}" yield { "name": target, "actions": [ (render_template, [j2_template], {}), ], # 把数据源加入文件依赖,配置改动时自动触发重渲染 "file_dep": [j2_template, DATA_SOURCE_PATH], "targets": [target], "clean": True, }
关键改动说明
- 移除硬编码的
account_details列表,改为渲染前实时从外部文件读取,保证每次渲染都用最新配置 - 所有文件读写操作统一指定
utf-8编码,避免跨环境中文乱码问题 - 数据源文件加入doit的
file_dep依赖列表,完全适配增量构建逻辑:模板、数据源任意一个文件改动才会重跑渲染任务,无改动时直接跳过,不做无效执行 - 数据读取逻辑单独封装为
load_account_data函数,后续如果要切换为CSV、TOML等其他存储格式,只需要修改这个函数的内部逻辑即可,渲染和任务调度代码无需改动
内容的提问来源于stack exchange,提问作者Daemon
相关产品推荐
相关产品推荐

