通过add_job_flow_steps向EMR传递嵌套字典出现截断报错问题
EMR嵌套JSON参数截断问题解决方案
根本原因
该截断问题由多层转义字符的Shell解析冲突导致:EMR执行步骤时会通过Shell解析传入的命令参数,嵌套JSON内部的转义双引号会被Shell误判为参数的结束边界,嵌套层级越多转义冲突概率越高,因此扁平字典可正常传递,嵌套字典会出现内容截断。
可行解决方案
方案1:Base64编码传递(最推荐,无转义兼容性问题)
发送端构造参数时,先将JSON字符串做Base64编码,传递纯编码字符串完全规避特殊字符解析问题。
发送端(构造EMR步骤参数侧)代码:
import json import base64 my_dict = {"level_one_key": {"level_two_key": "level_two_value"}} json_str = json.dumps(my_dict) # 编码为无特殊字符的base64字符串 encoded_param = base64.b64encode(json_str.encode("utf-8")).decode("utf-8") # 直接将encoded_param作为--my_dict的参数传入add_job_flow_steps接口即可
接收端(execute.py)代码:
import argparse import json import base64 parser = argparse.ArgumentParser() parser.add_argument('--my_dict', type=str, required=False) args = parser.parse_args() if args.my_dict: # 先解码base64再解析JSON raw_json = base64.b64decode(args.my_dict).decode("utf-8") my_dict = json.loads(raw_json)
方案2:调整参数引号包裹规则
构造参数时使用单引号包裹JSON字符串,避免内部双引号与外层包裹符冲突,构造后的参数形式如下:
--my_dict '{"level_one_key": {"level_two_key": "level_two_value"}}'
该方案存在不同EMR版本的兼容性风险,仅适合临时测试使用。
方案3:S3中转传递(适合大体积元数据)
若元数据字典体积较大,可先将JSON内容写入文件上传到S3,仅将S3路径作为参数传递给execute.py,脚本运行时从S3拉取文件内容再解析,完全规避命令行参数的长度、转义限制。
内容的提问来源于stack exchange,提问作者fjjones88
相关产品推荐
相关产品推荐

