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.

Two Way Serialization

See original GitHub issue

Trying to cope with this without writing two schemes for the same stuff.

Let’s say I’m taking in one API and it gives me something like this:

{ 
 "CamelCased": "Stuff",
 "somethingElse": "More stuff",
 "OhLookAList": [1,2,3,4]
}

And I’m repackaging it, doing some fun stuff internally, and then dumping it out the other side into my own API. Don’t ask why I can’t keep the same names.

{
 "camel_cased": "That's a lie now.",
 "something_else": "More stuff",
 "oh_look_a_list": [1,2,3,4]
}

Normally I’d just use dump_to/load_from and be done with it all…however, I need to reverse the flow and send information from my API back to the external API. So someone will post:

{
 "camel_cased": "That's a lie now.",
 "something_else": "More stuff",
 "oh_look_a_list": [1,2,3,4]
}

And the external API will get…

{ 
 "CamelCased": "Stuff",
 "somethingElse": "More stuff",
 "OhLookAList": [1,2,3,4]
}

In the example text for marshmallow-enum I used a (nasty, in my opinion) pre_load/pre_dump workaround that looked at the schema context to see if the incoming data was the internal source or external source, and then switched a value on the field. However, I’m hesitant to do that for an entire schema.

The best way I can think to handle this with Marshmallow is to just some sort of schema factory that’d create external/internal schemas on demand, potentially a less crappy version of this:

def make_two_way_schema(context):
     class SomeSchema(Schema):
         id = fields.Str(load_from=context['id']['read'], dump_to=context['id']['write'])
     return SomeSchema(...)

However, I’m unplussed about this idea or the prospect of managing two sets of schemas. I could see manufacturing the schemas before hand – using the above mechanism – and then at dump/load time choose the correct one. Maybe something like…

def make_two_way_schema(mapping):
      internal_to_external = ...
      external_to_internal = ...

      def schema_choose(...): # all the same args as Schema.__init__
          return internal_to_external if context['source'] == 'internal' else external_to_internal
      return schema_choose

This strikes me as the lesser of two evils but not by much… Any ideas?

Issue Analytics

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

github_iconTop GitHub Comments

2reactions
jhitzecommented, Mar 25, 2016

They way I’ve handled this is not always dump. load_from is an additional field to the one specified to the left of the equal sign.

SomeSchema

class SomeSchema(Schema):
    long_name = fields.String(load_from="longName", dump_to="longName")

Comes in as camelCase, and we want camelCase out

some_schema = SomeSchema()
data, errors = some_schema.load({"longName" : "Marshmallows for the masses"})
dump_data, errors = some_schema.dump(data)

# dump_data will return
# {"longName" : "Marshmallows for the masses"}

Comes in as camelCase, and we want snake_case out

some_schema = SomeSchema()
data, errors = some_schema.load({"longName" : "Marshmallows for the masses"})

# data will return
# {"long_name" : "Marshmallows for the masses"}

Comes in as snake_case, and we want camelCase out

some_schema = SomeSchema()
data, errors = some_schema.load({"long_name" : "Marshmallows for the masses"})
dump_data, errors = some_schema.dump(data)

# dump_data will return
# {"longName" : "Marshmallows for the masses"}

Comes in as snake_case, and we want snake_case out

some_schema = SomeSchema()
data, errors = some_schema.load({"long_name" : "Marshmallows for the masses"})

# data will return
# {"long_name" : "Marshmallows for the masses"}

Let me know if that helps!

1reaction
killthekittencommented, Aug 1, 2019

Hey, for the history, @sloria added a code example that solves it recently. Also, #1295

Read more comments on GitHub >

github_iconTop Results From Across the Web

Different Serialization Approaches for Java - Baeldung
Java specifies a default way to serialize objects. ... We can implement these two methods inside the class that we want to serialize....
Read more >
Serialization and Deserialization in Java with Example
Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte ......
Read more >
Serialization in Java - DigitalOcean
Serialization in Java allows us to convert an Object to stream that we can send over ... It's written in this way to...
Read more >
Serialization - Wikipedia
In computing, serialization (or serialisation) is the process of translating a data ... Since both serializing and deserializing can be driven from common...
Read more >
Serialization and Unserialization, C++ FAQ - Standard C++
How do I serialize objects that are part of an inheritance hierarchy and ... The easiest way to handle this is to anoint...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

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