Introduction
Marshmallow, stylized as “marshmallow”, is an object-relational mapping library which is used to convert objects to and from Python data types. It is often used alongside SQLAlchemy, an ORM that maps database schemas to Python objects. Marshmallow is often used to deserialize Python dicts to SQLAlchemy models and vice versa. Let’s focus on how to use Marshmallow.
Creating Schemas
First, we need to create a schema to model the thing we want to serialize and deserialize. Let’s create a model for our schema, called Student.
import datetime as dt
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
self.created_at = dt.datetime.now()
Next, create the Schema using a class that maps attribute names to field objects.
from marshmallow import Schema, fields
class StudentSchema(Schema):
name = fields.Str()
grade = fields.Str()
created_at = fields.DateTime()
Serializing Objects
We pass the object into the schema’s dump(s) method to serialize (object to Python type), and we use the method dumps() to return a JSON-encoded string or dump() if we want to return a dict of the object.
student = Student(name="Minh", grade="A+")
schema = StudentSchema()
result = schema.dumps(student)
# '{"name": "Minh", "grade": "A+", created_at": "2020-11-2T05:26:03.869245"}'
# We can also filter which fields we want to output
short_schema = StudentSchema(only=("name", "grade"))
short_schema.dump(user)
# {"name": "Minh", "grade": "A+"}
Deserializing Objects
Deserializing or loading, validates an Python dictionary to an application-level data structure. By default the load method will return a Python dict with the field names mapping to the value.
user_data = {
"created_at": "2020-11-2T05:26:03.869245",
"grade": "A+",
"name": "Minh",
}
schema = StudentSchema()
result = schema.load(user_data)
# {'name': 'Minh',
# 'grade': 'A+',
# 'created_at': datetime.datetime(2020, 11, 2, 5, 26, 3, 869245)},
Deserializing to Objects
Result will return a Student instance if we add the @post_load declaration and the method to be ran after loading.
from marshmallow import Schema, fields, post_load
class StudentSchema(Schema):
name = fields.Str()
grade = fields.Str()
created_at = fields.DateTime()
@post_load
def make_student(self, data, **kwargs):
return User(**data)
user_data = {"name": "Minh", "grade": "A+"}
schema = StudentSchema()
result = schema.load(user_data)
print(result) # => <User(name='Minh')>
Hopefully this guide has been a useful introduction to Marshmallow and object serialization in Python. Happy blogging!
