开发UDTF解析数据记录内容,但部分数据会报错,使用的应该是python2
核心方法代码:
def process(self, table_name, file_path, content, *outcol):
definition = json.loads(self.dic[table_name][file_path])
#content.encode('utf-8', 'replace')
result = {}
result['content'] = content
# 解析过程
if definition.has_key('schema'):
self.parser_route(content, definition['schema'], result)
# 输出结果组装
out = []
for col in outcol:
if result.has_key(col):
out.append(result[col])
else:
out.append(None)
tupleout = tuple(out)
if( len(tupleout) > 0 ):
self.forward(*tupleout)
2022-08-09 17:25:25,630 ERROR [BaseBatchJob.java:272] - Failure Reason:
2022-08-09 17:25:25,630 ERROR [BaseBatchJob.java:274] - ODPS-0123055:Script exception - Traceback (most recent call last):
2022-08-09 17:25:25,631 ERROR [BaseBatchJob.java:274] - File "<LOG_PARSE_UDTF.py>", line 49, in process
2022-08-09 17:25:25,632 ERROR [BaseBatchJob.java:274] - self.forward(*tupleout)
2022-08-09 17:25:25,632 ERROR [BaseBatchJob.java:274] - UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-6: ordinal not in range(128)
代码能正常执行
参考MaxCompute UDF(Python)常见问题 https://help.aliyun.com/document_detail/317787.html#section-u3c-7of-jue
其中现象二
return ret.encode('utf-8')
又报了另外的错:
2022-08-09 17:31:07,431 ERROR [BaseBatchJob.java:272] - Failure Reason:
2022-08-09 17:31:07,432 ERROR [BaseBatchJob.java:274] - ODPS-0123055:Script exception - Traceback (most recent call last):
2022-08-09 17:31:07,434 ERROR [BaseBatchJob.java:274] - File "<LOG_PARSE_UDTF.py>", line 48, in process
2022-08-09 17:31:07,434 ERROR [BaseBatchJob.java:274] - tupleout.encode('utf-8')
2022-08-09 17:31:07,434 ERROR [BaseBatchJob.java:274] - AttributeError: 'tuple' object has no attribute 'encode'
返回结果是一个元组,所以不知道这里应该怎么处理?
代码中也尝试将原始记录内容做编码转换
报了如下的错:
2022-08-09 17:06:26,011 ERROR [BaseBatchJob.java:272] - Failure Reason:
2022-08-09 17:06:26,011 ERROR [BaseBatchJob.java:274] - ODPS-0123055:Script exception - Traceback (most recent call last):
2022-08-09 17:06:26,011 ERROR [BaseBatchJob.java:274] - File "<LOG_PARSE_UDTF.py>", line 34, in process
2022-08-09 17:06:26,012 ERROR [BaseBatchJob.java:274] - content.encode('utf-8', 'replace')
2022-08-09 17:06:26,012 ERROR [BaseBatchJob.java:274] - UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 262: ordinal not in range(128)
2022-08-09 17:06:26,012 ERROR [BaseBatchJob.java:274] -
2022-08-09 17:06:26,012 ERROR [BaseBatchJob.java:274] -
实际通过异常抛出,发现处理的字符串中有一些特殊字符,类似:2741-��ʫ��-220808M-20220808-121457
无论使用什么编码方法,都不能针对这类字符串进行转换处理
最后只能使用兜底代码,解决了问题
import sysreload(sys)sys.setdefaultencoding('utf-8')
但使用这个代码的缺点是受沙箱限制,调用udf的sql语句中必须增加参数设置
set odps.isolation.session.enable = true;
out.append(result[col]) ,可以改成
if isinstance(result[col], str):
out.append(result[col])
elif isinstance(result[col], unicode):
out.append(result[col].encode('utf-8'))
1、问题的根因,其实在MaxCompute UDF(Python)常见问题中已经解答了,核心原因是编码格式转换报错;
2、要解决问题,首先要搞清楚,tupleout里面存储的对象是什么类型及编码格式?
建议增加如下代码尝试:
import detect
result = chardet.detect(result[col])
print result
看下字符串到底是啥类型的,然后使用result[col].encode('utf-8')转换
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
MaxCompute(原ODPS)是一项面向分析的大数据计算服务,它以Serverless架构提供快速、全托管的在线数据仓库服务,消除传统数据平台在资源扩展性和弹性方面的限制,最小化用户运维投入,使您经济并高效的分析处理海量数据。