2016-04-25 106 views
1

我有以下對象。Python Marshmallow:schema.loads()爲嵌套模式返回錯誤

class Notification(object): 
    def __init__(self, **kwargs): 
     self.name = kwargs.get('name', '') 
     self.locale = kwargs.get('locale', '') 
     self.text = kwargs.get('text', '') 

    def __repr__(self): 
     return '<Notification(name={self.name!r})>'.format(self=self) 


class NotificationThrottle(object): 
    def __init__(self, **kwargs): 
     self.notification = kwargs.get('notification', '') 
     self.time_span = kwargs.get('time_span', '') 
     self.maximum_count = kwargs.get('maximum_count', '') 
     self.current_count = kwargs.get('current_count', '') 
     self.throttle_set_date = kwargs.get('throttle_set_date', '') 

    def __repr__(self): 
     return '<NotificationThottle(name={self.type!r})>'.format(self=self) 

...和下​​面所附的棉花糖模式

from marshmallow import Schema, fields, post_load 

class NotificationSchema(Schema): 
    name = fields.Str() 
    locale = fields.Str() 
    text = fields.Str() 

    @post_load 
    def make_notification(self, data): 
     return Notification(**data) 


class NotificationThrottleSchema(Schema): 
    notification = fields.Nested(NotificationSchema) 
    time_span = fields.Int() 
    maximum_count = fields.Int() 
    current_count = fields.Int() 
    throttle_set_date = fields.DateTime() 

    @post_load 
    def make_notification_throttle(self, data): 
     return NotificationThrottle(**data) 

數據如下:

notification_data = { 
    'name': "new_message", 
    'locale': "sw_KE", 
    'text': "mimi ni mzee" 
} 
notification_throttle_data = { 
    "time_span": 3600, 
    "maximum_count": 10, 
    "current_count": 1, 
    "throttle_set_date": datetime.utcnow().isoformat()} 

我在嘗試加載上面的NotificationThrottleSchema時下面的錯誤。

In [1]: from datetime import datetime 

In [2]: from .schemas.throttle_schemas import NotificationSchema, NotificationThrottleSchema 

In [3]: notification_data = { 
     'name': "new_message", 
     'locale': "sw_KE", 
     'text': "mimi ni mzee" 
    } 

In [4]: notification_throttle_data = { 
     "time_span": 3600, 
     "maximum_count": 10, 
     "current_count": 1, 
     "throttle_set_date": datetime.utcnow().isoformat()} 

In [5]: schema = NotificationSchema() 

In [6]: notif_schema = schema.load(notification_data) 

In [7]: notif = notif_schema.data 

In [8]: notif 
Out[8]: <Notification(name=u'new_message')> 

In [9]: notification_throttle_data.update({'notification':notif}) 

In [10]: notification_throttle_data 
Out[10]: 
{'current_count': 1, 
'maximum_count': 10, 
'notification': <Notification(name=u'new_message')>, 
'throttle_set_date': '2016-04-25T08:19:06.492310', 
'time_span': 3600} 

In [11]: notif_throttle_schema = NotificationThrottleSchema() 

In [12]: notif_throttle = notif_throttle_schema.load(notification_throttle_data) 

In [13]: notif_throttle 
Out[13]: UnmarshalResult(data={'current_count': 1, 'maximum_count': 10, 'throttle_set_date': datetime.datetime(2016, 4, 25, 8, 19, 6, 492310), 'time_span': 3600}, errors={'notification': {u'_schema': [u'Invalid input type.']}}) 

In [14]: notif_throttle.data 
Out[14]: 
{'current_count': 1, 
'maximum_count': 10, 
'throttle_set_date': datetime.datetime(2016, 4, 25, 8, 19, 6, 492310), 
'time_span': 3600} 

In [15]: 

正如您所看到的,對NotificationThrottle類型的對象進行反序列化失敗,並顯示上面的神祕錯誤。 我相信,這是一個棉花糖本身的問題,除非我誤解了post_load方法的工作(它大概會返回定義的對象)

有什麼我做錯了嗎?

回答

3

您似乎正在使用通知對象更新notification_throttle_data而不是序列化對象。 https://marshmallow.readthedocs.org/en/latest/quickstart.html#serializing-objects-dumping

你想要做的是:

notif_data = schema.dump(notification_data) 
    notification_throttle_data.update({'notification':notif_data.data})  
    notif_throttle = notif_throttle_schema.load(notification_throttle_data) 

UnmarshalResult(data=<__main__.NotificationThrottle object at 0x10a3d5a90>, errors={})