Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-SQLAlchemy-Marshmallow Nesting

I'm trying to serialize data from a One-To-Many relationship models using Marshmallow in Flask. I read the Marshmallow and SQLAlchemy docs, but couldn't make it work. Could anyone help me.

Models:

class Category(db.Model):
    __tablename__ = 'category_mn'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(45))
    status = db.Column(db.Integer, server_default=db.FetchedValue())
    items = db.relationship('Items', backref='category', lazy='dynamic')
    timestamp = db.Column(db.DateTime, server_default=db.FetchedValue())


class Items(db.Model):
    __tablename__ = 'items_mn'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100))
    category_id = db.Column(db.Integer, db.ForeignKey('category_mn.id'))
    timestamp = db.Column(db.DateTime, server_default=db.FetchedValue())

Schemas:

class CatSchema(ma.ModelSchema):
    class Meta:
        model = Category
        fields = ('id', 'name', 'status')


class ItemSchema(ma.ModelSchema):

    class Meta:
        model = Items
        fields = ('id', 'name')
    category = ma.Nested(CatSchema, many=True)

I'm looking for an output like this:

[{'id':1, 'name':'Test', 'category':{'id':1, 'name':'Test Cat'}}]
like image 673
Karthik Avatar asked Jun 13 '17 01:06

Karthik


People also ask

Why marshmallow is used in flask?

Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmallow (an object serialization/deserialization library) that adds additional features to marshmallow, including URL and Hyperlinks fields for HATEOAS-ready APIs. It also (optionally) integrates with Flask-SQLAlchemy.

What is Marshmallow SQLAlchemy?

Marshmallow is a Python library that converts complex data types to and from Python data types. It is a powerful tool for both validating and converting data.

What is nested in marshmallow?

Schemas can be nested to represent relationships between objects (e.g. foreign key relationships). For example, a Blog may have an author represented by a User object. Use a Nested field to represent the relationship, passing in a nested schema.


1 Answers

You're referencing models that don't exist in your schemas.

Besides that, category in Items is not iterable (it's the "one" side of the "one-to-many" relationship), so the many=True parameter throws an error.

And category should appear in the fields attribute of the Meta class for ItemSchema so it actually appears in the serialization.

It should be like this:

class CatSchema(ma.ModelSchema):
  class Meta:
    model = Category
    fields = ('id', 'name', 'status')


class ItemSchema(ma.ModelSchema):

  class Meta:
    model = Items
    fields = ('id', 'name', 'category')
  category = ma.Nested(CatSchema)

Of course, you could simply not include the fields attribute in the meta classes at all, since model is already taking care of mapping the models.

like image 148
Luis Orduz Avatar answered Nov 16 '22 00:11

Luis Orduz