我正在尝试使用棉花糖模式序列化python对象。下面是我为数据定义的架构。
from marshmallow import Schema, fields
class User:
def __init__(self, name = None, age = None, is_active = None, details = None):
self.name = name
self.age = age
self.is_active = is_active
self.details = details
class UserSchema(Schema):
name = fields.Str()
age = fields.Int()
is_active = fields.Bool()
details = fields.Dict()
输入将以字典格式,所有值将为字符串。
user_data = {"name":"xyz", "age":"20", "is_active": 'true',"details":"{'key1':'val1', 'key2':'val2'}"}
当我尝试运行以下代码段时, age 和 is_active 的值已转换为各自的数据类型,但详细信息保持不变。>
user_schema = UserSchema()
user_dump_data = user_schema.dump(user_data)
print(user_dump_data)
输出:
{'name': 'xyz', 'is_active': True, 'details': "{'key1':'val1', 'key2':'val2'}", 'age': 20}
我需要将输入数据序列化为我在架构中定义的相应数据类型。我做错了什么吗?谁能指导我如何使用棉花糖实现这一目标?
我正在使用
python 3.6
marshmallow 3.5.1
修改
上述输入数据是从HBase获取的。默认情况下,HBase将其所有值存储为字节,并以字节返回。下面是我从HBase获得的格式
{b'name': b'xyz', b'age': b'20', b'is_active': b'true', b'details': b"{'key1':'val1', 'key2':'val2'}"}
然后我解码该词典并将其传递给我的UserSchema,以序列化它以在Web API中使用。
答案 0 :(得分:1)
您混淆了序列化(转储)和反序列化(加载)。
转储从对象形式到json可序列化的基本python类型(使用Schema.dump
)或json字符串(使用Schema.dumps
)。加载是相反的操作。
通常,您的API从外界加载(并验证)数据,并将您的对象(未经验证)转储到外界。
如果输入数据是此数据,并且想要将其加载到对象中,则需要使用load
,而不是dump
。
user_data = {"name":"xyz", "age":"20", "is_active": 'true',"details":"{'key1':'val1', 'key2':'val2'}"}
user_loaded_data = user_schema.load(user_data)
user = User(**user_loaded_data)
除非您这样做,否则将被另一个问题困扰。 DictField
期望数据为dict
,而不是str
。您需要输入
user_data = {"name":"xyz", "age":"20", "is_active": 'true',"details": {'key1':'val1', 'key2':'val2'}}
答案 1 :(得分:1)
正如Jérôme所述,您将序列化(转储)与反序列化(加载)混为一谈。根据您的要求,应按照建议使用Schema.load
。
因为,所有输入值都应为字符串类型。您可以使用pre_load
注册用于预处理数据的方法,如下所示:
from marshmallow import Schema, fields, pre_load
class UserSchema(Schema):
name = fields.Str()
age = fields.Int()
is_active = fields.Bool()
details = fields.Dict()
@pre_load
def pre_process_details(self, data, **kwarg):
data['details'] = eval(data['details'])
return data
user_data = {"name":"xyz", "age":"20", "is_active": 'true',"details":"{'key1':'val1', 'key2':'val2'}"}
user_schema = UserSchema()
user_loaded_data = user_schema.load(user_data)
print(user_loaded_data)
在这里,pre_process_details
会将字符串类型转换为字典以进行正确的反序列化。