Redshift调用Python Lambda UDF报错8001:无效外部函数响应
问题原因
- 错误码8001的核心触发逻辑是Redshift要求Lambda UDF返回的结果行数必须和请求传入的行数完全相等,你提供的请求payload中
num_records值为1,说明Redshift本次向Lambda传入了1行参数,要求Lambda返回的results数组长度必须严格等于1。 - 你现有代码存在两处不符合Redshift Lambda UDF协议的问题:
- 手动对返回结果做了
json.dumps序列化:Python Lambda运行时会自动将返回的字典对象序列化为JSON,手动序列化后返回的是JSON字符串,不是结构化的JSON对象,Redshift无法正常解析results字段。 results字段格式不符合要求:如果你的DoJob()返回的是单个结果值(比如执行成功标识、邮件ID等),直接赋值给results会导致该字段不是数组类型,或者数组长度和输入行数不匹配,就会触发“Extra rows”报错。
- 手动对返回结果做了
- 额外小问题:你贴出的调用SQL中最后一个参数
'sample subject缺少闭合单引号,若实际执行语句也是如此会导致语法错误,需确认是否为粘贴失误。
修复方案
修正后的Lambda代码示例如下:
def lambda_handler(event, context): # 执行业务逻辑 result = DoJob() # 构造符合Redshift要求的返回结构 ret = dict() # results必须是长度等于输入行数的数组,此处输入行数为1,所以把结果包进数组 ret['results'] = [result] # 直接返回字典即可,不需要手动序列化 return ret
如果你的UDF需要支持批量多行输入,可以按如下逻辑处理:
def lambda_handler(event, context): results = [] # 遍历所有传入的行参数,逐行处理 for row_args in event['arguments']: # row_args是当前行的所有参数列表,按顺序对应你调用UDF时传入的参数 sender = row_args[0] recipient = row_args[1] body = row_args[2] subject = row_args[3] # 执行业务逻辑 row_result = DoJob(sender, recipient, body, subject) results.append(row_result) return { "results": results }
内容的提问来源于stack exchange,提问作者Soundararajan
相关产品推荐
相关产品推荐

