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

ruamel.yaml序列化丢失锚点且跳过同层级后续别名问题排查

关于ruamel.yaml处理YAML合并键(<<)顺序式别名的问题

问题场景

原始YAML配置内容:

---
sp-database: &sp-database
  DATABASE_NAME: blah
  DATABASE_PORT: 5432
  DATABASE_SCHEMA: public
  DATABASE_USERNAME: foo
  DATABASE_DRIVER: bar
  DATABASE_TYPE: pg

rabbit: &rabbit
  RABBIT_PORT: 5672
  RABBIT_USERNAME: foo

sp-env: &sp-env
  <<: *sp-database
  <<: *rabbit
  REDIS_PORT: 6379

使用以下Python代码读取并转储该YAML:

def blah(self):
    values_file = './src/values.yaml'
    with open(values_file, 'r') as stream:
        data = self.yaml.load(stream)
    values_file='./src/values1.yaml'
    with open(values_file, 'w') as file:
        self.yaml.indent(sequence=4, offset=2)
        self.yaml.dump(data, file)

操作中遇到问题:ruamel.yaml会丢失锚点信息,并且跳过同层级第一个<<:后的其他别名,最终转储的结果只保留了第二个别名的合并内容。将合并键改为数组形式后即可正常工作:

sp-env: &sp-env
  <<: [ *sp-database, *rabbit ]
  REDIS_PORT: 6379

原因解析

  • YAML规范对重复键的定义:YAML核心规范中,同一个映射表(字典)内不允许存在重复键。多数解析器处理重复键时,只会保留最后一个出现的键值对。连续写两个<<:属于重复键<<的写法,不符合规范推荐用法。
  • ruamel.yaml的解析逻辑:ruamel.yaml解析重复的<<键时,会直接用后一个值覆盖前一个,导致第一个别名*sp-database的合并逻辑被丢弃。同时锚点信息在解析过程中无法被正确保留——因为解析后的内存结构里没有多个合并项的记录,转储自然无法还原原始的顺序式别名写法。
  • 数组形式的合法性:YAML规范明确支持合并键的值为别名数组,这种写法会让解析器依次合并数组中每个别名指向的映射表内容,属于标准合并用法。ruamel.yaml能正确识别这种结构,保留合并逻辑与锚点信息,因此转储后能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 16:06:28