question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Serializing dict of nested schema at the top level

See original GitHub issue

Hi all,

I am using marshmallow 3.0.0b16. I am trying to write a REST endpoint that wants to return a json dictionary of objects. The python signature looks something like:

class Foo():
  def __init__(a: str, b: int):
    pass

def myEndpoint() -> Dict[str, Foo]:
  return { "a": Foo("a", 1), "b": Foo("b", 2) }

The FooSchema is pretty trivial to write, however when I want to write the schema for the dict, I found I have to wrap it with another top level object in order to get to dump correctly.

class FooDictSchema(Schema):
  foo_dict = fields.Dict(key=field.String(), value=field.Nested(FooSchema))

This works for dumping but injects an unnecessary "foo_dict" key at the top level of the json object, when I tried doing schema = FooSchema(many=true) and dumping the dict, i get a bunch of empty values.

Is there an easy way to dump a dictionary directly where it uses a nested type? This is very similar to the following issue: https://github.com/marshmallow-code/marshmallow/issues/483 but my usecase requires the nested dict to be at the top level.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:18 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
vit-zikmundcommented, May 19, 2022

Hi @sloria, sorry to necromance on this closed issue, but isn’t the from_dict a rather resource heavy approach? I know it solves the problem, but if I understand it well, it creates a disposable schema with N fields for N keys in the dictionary, right? Seems more like a workaround than a solution.

I understand working directly with a dict might not fit in the whole marshmallow concept of Schemas being objects, but I think one could pretty easily use the serialize/deserialize interface of the field directly. I’ve developed a little example how this could work:

from dataclasses import dataclass
from marshmallow.fields import Dict, Nested
from marshmallow_dataclass import add_schema


@add_schema
@dataclass(frozen=True)
class Record:
    item_str: str
    item_float: float


dict_field = Dict(values=Nested(Record.Schema))

data = {'a': Record('a', 1.0), 'b': Record('b', 2.0), 'c': Record('c', 3.0)}
print(data)
serialized_data = dict_field.serialize('n/a', data, accessor=lambda obj, _attr, _default: obj)
print(serialized_data)
data_back = dict_field.deserialize(serialized_data)
print(data_back)

The output is as expected:

{'a': Record(item_str='a', item_float=1.0), 'b': Record(item_str='b', item_float=2.0), 'c': Record(item_str='c', item_float=3.0)}
{'a': {'item_str': 'a', 'item_float': 1.0}, 'b': {'item_str': 'b', 'item_float': 2.0}, 'c': {'item_str': 'c', 'item_float': 3.0}}
{'a': Record(item_str='a', item_float=1.0), 'b': Record(item_str='b', item_float=2.0), 'c': Record(item_str='c', item_float=3.0)}

The accessor for serialize is a little hacky, but one could wrap that to a dump/load method just for the Dict field. Maybe 😃

2reactions
lauwerscommented, Jun 27, 2020

I don’t think this addresses one of the earlier requirements, which was for a dictionary with unknown keys (issue #120):

https://github.com/marshmallow-code/marshmallow/issues/120

Was there ever any progress made on supporting that use case? I continue to use my own NamedObjectMap field (which i show in #120) but I would much rather use something that is officially maintained.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Top level lists and dictionaries with marshmallow
Top -level list of dicts is the normal case of using a schema with many=True. ... but those can still be defined in...
Read more >
Serializing (nested) data structures in a human-readable format
I am reinventing the wheel to write a function that serializes a (nested) data structure human readably. The default output is deliberately ...
Read more >
marshmallow -- simplified object serialization | We all are data.
Nested (ArtistSchema()) bowie = dict(name='David Bowie') album = dict(artist=bowie ... Serialize app-level objects to primitive Python types.
Read more >
Nesting Schemas — marshmallow 3.19.0 documentation
Schemas can be nested to represent relationships between objects (e.g. foreign key ... The serialized blog will have the nested user representation.
Read more >
Serializing complex nested JSON - Amazon Redshift
An alternate to methods demonstrated in this tutorial is to query top-level nested collection columns as serialized JSON. You can use the serialization...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found