Kedro模板配置无法将globals.yml加载至catalog.yml问题
问题背景
我在Kedro中构建数据管道,通过conf/base/globals.yml定义全局变量,在catalog.yml中使用${...}语法引用,但配置未生效,出现S3 Bucket名称无效的错误:
Invalid bucket name "${bucket}": Bucket name must match the regex "^[a-zA-Z0-9.\-_]{1,255}$" or be an ARN matching the regex "^arn:(aws).*:(s3|s3-object-lambda):[a-z\-0-9]*:[0-9]{12}:accesspoint[/:][a-zA-Z0-9\-.]{1,63}$|^arn:(aws).*:s3-outposts:[a-z\-0-9]+:[0-9]{12}:outpost[/:][a-zA-Z0-9\-]{1,63}[/:]accesspoint[/:][a-zA-Z0-9\-]{1,63}$"
我的配置文件如下:
conf/base/globals.yml
paths: base_path: "s3://my_project" datasets: pdf: "base.PDFDataSet" png: "pillow.ImageDataSet" csv: "pandas.CSVDataSet" excel: "pandas.ExcelDataSet" data_folders: raw: "01_raw" intermediate: "02_intermediate" primary: "03_primary" feature: "04_feature" model_input: "05_model_input" models: "06_models" model_output: "07_model_output" reporting: "08_reporting"
src/my_project/settings.py
from kedro.config import TemplatedConfigLoader CONFIG_LOADER_CLASS = TemplatedConfigLoader CONFIG_LOADER_ARGS = { "globals_pattern": "*globals.yml", }
conf/base/catalog.yml
_label_images: &label_images type: PartitionedDataSet path: "${paths.base_path}/data/${data_folders.raw}/label_images" dataset: ${datasets.png} label_images_png: <<: *label_images filename_suffix: .png label_images_jpg: <<: *label_images filename_suffix: .jpg label_images_jpeg: <<: *label_images filename_suffix: .jpeg label_images_pdf: <<: *label_images dataset: base.PDFDataSet filename_suffix: .pdf my_project_label_extracts: type: PartitionedDataSet path: s3://my_project/data/01_raw/label_extracts dataset: pandas.ExcelDataSet
问题根源
这个错误的核心是全局变量没有被Kedro的TemplatedConfigLoader正确渲染替换,导致catalog.yml中的${paths.base_path}没有被替换成s3://my_project,而是被直接当作S3 Bucket名称处理,而包含${}的字符串不符合S3 Bucket的命名规则,因此触发报错。
排查与解决方案
1. 修正settings.py中的配置加载参数
TemplatedConfigLoader的globals_pattern参数需要准确匹配全局配置文件,建议去掉通配符*,直接指定文件名,同时确保配置加载的环境参数正确:
from kedro.config import TemplatedConfigLoader CONFIG_LOADER_CLASS = TemplatedConfigLoader CONFIG_LOADER_ARGS = { "globals_pattern": "globals.yml", # 明确匹配base目录下的globals.yml "base_env": "base", "default_run_env": "local" }
如果你的Kedro版本低于0.18.x,可能需要使用globals_file参数指定完整路径:
CONFIG_LOADER_ARGS = { "globals_file": "conf/base/globals.yml" }
2. 验证全局配置文件的加载状态
运行以下命令查看Kedro是否正确加载了全局变量:
kedro config list --verbose
在输出中检查是否包含globals.yml的内容(比如paths.base_path: s3://my_project),如果没有,说明全局配置文件未被加载,需要检查文件路径和权限。
3. 简化测试验证模板渲染
在catalog.yml中添加一个简单的测试数据集,排除PartitionedDataSet的干扰:
test_csv: type: pandas.CSVDataSet path: "${paths.base_path}/data/${data_folders.raw}/test.csv"
然后启动Kedro IPython环境,尝试加载该数据集:
kedro ipython
在IPython中执行:
context.catalog.load("test_csv")
如果仍然报错,说明模板渲染确实未生效;如果成功加载,说明问题出在PartitionedDataSet的嵌套模板处理上。
4. 检查配置目录结构与优先级
确保conf/base目录下的globals.yml没有被其他环境(如conf/local)的同名文件覆盖,Kedro会优先加载conf/<env>下的配置,再合并conf/base的配置。
5. 确认Kedro版本兼容性
不同Kedro版本的TemplatedConfigLoader参数略有差异:
- Kedro 0.17.x及更早版本:使用
TemplatedConfigLoader需要手动指定globals_dict或globals_file - Kedro 0.18.x+:支持
globals_pattern参数匹配全局配置文件
可以通过以下命令查看Kedro版本:
kedro --version
内容的提问来源于stack exchange,提问作者Michael Bahchevanov

