计一次失败的python-udf处理PHP反序列化数据

         问题背景:公司后端用的是php,后端开发爸爸存数据的时候存的是php反序列化的数据,我们数据这边需要用到这些字段的信息,想着自己处理一下。

        所在环境:大数据平台使用的是阿里云的dataworks,直接函数处理是不行的,需要写个UDF,这边支持java和python的UDF,由于自己的java实在太差,所以搞不定,然后想用python处理下,由于之前写过python-udf有用过第三方包,所以本地测试了下代码,觉得可行,首先本地很简单的测试了下:

phpserialize包的文档:https://pypi.org/project/phpserialize/#description

# -*- coding: utf-8 -*-
import phpserialize as php
obj = 'a:1:{s:3:"sku";a:2:{i:14;a:3:{s:2:"id";i:14;s:4:"name";s:6:"尺码";s:5:"value";a:8:{i:0;s:5:"16041";i:1;s:4:"47.5";i:2;s:4:"47.5";i:3;s:0:"";i:4;s:0:"";i:5;s:0:"";i:6;s:0:"";i:7;s:0:"";}}i:15;a:3:{s:2:"id";i:15;s:4:"name";s:6:"颜色";s:5:"value";a:8:{i:0;s:5:"16057";i:1;s:7:"白/黑";i:2;s:7:"白/黑";i:3;s:0:"";i:4;s:0:"";i:5;s:0:"";i:6;s:0:"";i:7;s:0:"";}}}}'
adict = (php.loads(obj.encode(),decode_strings=True))
print(adict)

本地输出结果:{'sku': {14: {'id': 14, 'name': '尺码', 'value': {0: '16041', 1: '47.5', 2: '47.5', 3: '', 4: '', 5: '', 6: '', 7: ''}}, 15: {'id': 15, 'name': '颜色', 'value': {0: '16057', 1: '白/黑', 2: '白/黑', 3: '', 4: '', 5: '', 6: '', 7: ''}}}}

输出的json再用函数处理下就能用了。

然后开始写UDF:

from odps.udf import annotate
import phpserialize

@annotate("string->string")

class phpserialize_to_json(object):
    def evaluate(self, obj):
        adict = (phpserialize.loads(obj.encode(),decode_strings=True))
        return adict

然后调用这个UDF,报错,然后又给阿里云提工单,持续沟通,最后说不能引用第三方包(那我之前用numpy怎么解释),说pyodps支持部分第三方包,然后我就又用pyodps搞,把这个包的代码黏进来,然后再import这个包。

# -*- coding: utf-8 -*-
##@resource_reference{"phpserialize.py"}

import sys 
import os
sys.path.append(os.path.dirname(os.path.abspath('phpserialize.py'))) #将资源引入工作空间


import phpserialize as php
obj = 'a:1:{s:3:"sku";a:2:{i:14;a:3:{s:2:"id";i:14;s:4:"name";s:6:"尺码";s:5:"value";a:8:{i:0;s:5:"16041";i:1;s:4:"47.5";i:2;s:4:"47.5";i:3;s:0:"";i:4;s:0:"";i:5;s:0:"";i:6;s:0:"";i:7;s:0:"";}}i:15;a:3:{s:2:"id";i:15;s:4:"name";s:6:"颜色";s:5:"value";a:8:{i:0;s:5:"16057";i:1;s:7:"白/黑";i:2;s:7:"白/黑";i:3;s:0:"";i:4;s:0:"";i:5;s:0:"";i:6;s:0:"";i:7;s:0:"";}}}}'
adict = (php.loads(obj.encode(),decode_strings=True))
print(adict)

然后又是报错,UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 60: ordinal not in range(128)

又去百度看了半天,不知道啥问题,就知道是encode编码的问题,但是如果这里不encode,输出结果是:{'sku': {14: {'id': 14, 'value': {0: '16041', 1: '47.5', 2: '47.5', 3: '', 4: '', 5: '', 6: '', 7: ''}, 'name': '\xe5\xb0\xba\xe7\xa0\x81'}, 15: {'id': 15, 'value': {0: '16057', 1: '\xe7\x99\xbd/\xe9\xbb\x91', 2: '\xe7\x99\xbd/\xe9\xbb\x91', 3: '', 4: '', 5: '', 6: '', 7: ''}, 'name': '\xe9\xa2\x9c\xe8\x89\xb2'}}}

这个结果到了hive里也处理不了,也可能是我不知道怎么处理

 

 

总结:1、公有云也好,但是比着自建,服务就没那么好了,自建你的开发人员就是使用者的客服,很多问题可以自己探讨的

           2、多学习吧,不会java真的不行

          3、最后又看了看需求,要做的东西不需要处理这个反序列化,真的是替自己觉得傻逼

          4、开发内部多保持一致,大家都用json不就好了嘛

          5、接上一条,我觉得开发工作还是有共通性的(虽然我不是开发),比如大家都会用数组和循环,所以学习数据结构与算法是前后端都要学的,这些也是编程的基础吧,多学习多进步。

你可能感兴趣的:(hive,数据仓库)