如何在Python中将yaml主体作为字符串存储到yaml密钥中?

jei2mxaa  于 2023-06-28  发布在  Python
关注(0)|答案(1)|浏览(138)

我有一个配置Map如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-string-configmap
data:
  config: |
    timeout: 20m
    images:
      generator: "gcr.io/xxx/xxx/generator:v0.0.1"

从这里可以看出,config是一个字符串,从技术上讲也是yaml。
在python中阅读为:

with open(f"conf-configmap.yaml",'r') as f:
        config_string=yaml.safe_load(f)
        config_yaml = yaml.safe_load(config_string['data']['config'])
        config_yaml['images']['generator']="gcr.io/xxx/xxx/generator:v0.0.2"

我能够读取和修改yaml的内部属性。但是,现在我想用新的yaml覆盖yaml文件。

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-string-configmap
data:
  config: |
    timeout: 20m
    images:
      generator: "gcr.io/xxx/xxx/generator:v0.0.1"

我尝试了以下操作:

config_string['data']['config']=yaml.dump(config_yaml)
yaml.dump(config_string,conf-configmap.yaml)

但是,这将创建yaml为:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-string-configmap
data:
  config: 
    timeout: 20m
    images:
      generator: "gcr.io/xxx/xxx/generator:v0.0.1"

config的内部主体最初是一个多行字符串,现在变成了一个yaml对象。
我如何将内部主体保持为字符串本身?我在用pyyaml

jdzmm42g

jdzmm42g1#

输入中的config值是一个块样式的文本标量。PyYAML可以将所有字符串转储为标量,但仅以这种方式发出一个特定的标量是不平凡的。
如果您可以升级到ruamel.yaml,它还允许您保留注解,多余的引号(对于generator的值),并支持YAML 1.2,可以通过以下方式完成:

import sys
import io
import ruamel.yaml
from pathlib import Path

file_in = Path('conf-configmap.yaml')

yaml = ruamel.yaml.YAML(typ=['rt', 'string'])
yaml.preserve_quotes = True
data = yaml.load(file_in)
config_yaml = yaml.load(data['data']['config'])
config_yaml['images']['generator']="gcr.io/xxx/xxx/generator:v0.0.2"
data['data']['config'] = ruamel.yaml.scalarstring.LiteralScalarString(yaml.dump_to_string(config_yaml, add_final_eol=True))

yaml.dump(data, sys.stdout)

其给出:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-string-configmap
data:
  config: |
    timeout: 20m
    images:
      generator: "gcr.io/xxx/xxx/generator:v0.0.2"

要做到这一点,你需要运行:

pip install ruamel.yaml.string

在虚拟环境中

相关问题