JSON-сериализация с использованием Marshmallow - пропустите атрибуты None - PullRequest
1 голос
/ 11 марта 2019

Я использую Marshmallow для отправки экземпляра моего класса Decision в JSON.Тем не менее, это также сбросит атрибуты, которые None, например, мой атрибут score будет преобразован в null в JSON.После этого я не могу снова прочитать JSON, используя тот же подход.

https://repl.it/repls/VoluminousMulticoloredFacts

Последняя строка - это то место, где в данный момент происходит сбой.Мне нужно либо НЕ сбрасывать None в JSON, либо пропускать null во время загрузки:

import json
from marshmallow import Schema, fields, post_load

json_data = """{
    "appid": "2309wfjwef",
    "strategy": "First Strategy"
}"""

# Output class definition
class Decision(object):
    def __init__(self, appid = None, strategy = None, score = None):
        self.appid = appid
        self.strategy = strategy
        self.score = score

class DecisionSchema(Schema):
    appid = fields.Str()
    strategy = fields.Str()
    score = fields.Int()

    @post_load
    def make_decision(self, data):
        return Decision(**data)

# Deserialization into object
dec_json = json.loads(json_data)
schema = DecisionSchema()
dec = schema.load(dec_json).data

print(dec.strategy)

# Dump results back to JSON
schema = DecisionSchema()
out = schema.dumps(dec)

print(out.data)

# Load back from dump
schema = DecisionSchema()
dec = schema.load(out).data

#print(dec.strategy) # returns error currently

1 Ответ

1 голос
/ 12 марта 2019

«Официальный» ответ от команды разработчиков зефира можно найти в этом комментарии в трекере ошибок:

Используйте метод post_dump.

from marshmallow import Schema, fields, post_dump

class BaseSchema(Schema):
    SKIP_VALUES = set([None])

    @post_dump
    def remove_skip_values(self, data):
        return {
            key: value for key, value in data.items()
            if value not in self.SKIP_VALUES
        }


class MySchema(BaseSchema):
    foo = fields.Field()
    bar = fields.Field()


sch = MySchema()
sch.dump({'foo': 42, 'bar': None}).data  # {'foo': 42}

Как я отмечаю в дополнительном комментарии , есть недостаток: он также удалит None, когда allow_none поля равно True.

...