Himavan
Himavan

Reputation: 397

How to update nested objects in Flask-SQLAlchemy-Marshmallow

Could you help me to update nested objects in Flask-SQLAlchemy-Marshmallow. Here is the model

Parent Model

class ParentModel(db.Model):
    __tablename__ = "parent"

    id = db.Column(db.Integer, primary_key=True)
    parent_name = db.Column(db.String(100), nullable=False)
    
    childrens = db.relationship("ChildrensModel",  cascade="all,delete", backref='parent')

    @classmethod
    def find_by_id(cls, _id: int) -> "ParentModel":
        return cls.query.filter_by(id=_id).first()

    @classmethod
    def find_by_name(cls, name: int) -> "ParentModel":
        return cls.query.filter_by(parent_name=name).first()

    @classmethod
    def find_all(cls) -> List["ParentModel"]:
        return cls.query.all()

    def save_to_db(self) -> None:
        db.session.add(self)
        db.session.commit()

    def delete_from_db(self) -> None:
        db.session.delete(self)
        db.session.commit()

Children Model

class ChildrenModel(db.Model):
    __tablename__ = "children"

    id = db.Column(db.Integer, primary_key=True)
    children_name = db.Column(db.String(100), nullable=False)
    parent_id = db.Column(db.Integer,db.ForeignKey("parent.id") primary_key=True)

    @classmethod
    def find_by_id(cls, _id: int) -> "ChildrenModel":
        return cls.query.filter_by(id=_id).first()

    @classmethod
    def find_by_name(cls, name: int) -> "ChildrenModel":
        return cls.query.filter_by(children_name=name).first()

    @classmethod
    def find_all(cls) -> List["ChildrenModel"]:
        return cls.query.all()

    def save_to_db(self) -> None:
        db.session.add(self)
        db.session.commit()

    def delete_from_db(self) -> None:
        db.session.delete(self)
        db.session.commit()

Children Schema

class ChildrenSchema(ma.ModelSchema):


    class Meta:
        model = ChildrenModel
        include_fk = True

Parent Schema

class ParentSchema(ma.ModelSchema):

    children= fields.List(fields.Nested(ChildrenSchema(dump_only=("parent_id",))),required=True)

    class Meta:
        model = ParentModel
        include_fk = True

Here is the required JSON format. Could you please show me how to Update the existing nested object in following format.

{
  "parent_name":"parent1",
  "children":[{"children_name":"children_1"},{"children_name":"children_2"}]
}

And guys thankyou for your time.

Upvotes: 3

Views: 832

Answers (1)

snakecharmerb
snakecharmerb

Reputation: 55599

The nested schema specification must list the fields to include or exclude. This configuration:

from flask_marshmallow import Marshmallow
from marshmallow_sqlalchemy.fields import Nested

...

class ChildrenSchema(ma.SQLAlchemySchema):
    class Meta:
        model = ChildrenModel
        include_fk = False

    id = ma.auto_field()
    parent_id = ma.auto_field()
    children_name = ma.auto_field()


class ParentSchema(ma.SQLAlchemySchema):

    class Meta:
        model = ParentModel

    parent_name = ma.auto_field()
    children = Nested(
        ChildrenSchema, attribute='childrens',many=True, only=('children_name',)
    )

Would generate output like this:

{'parent_name': 'p1', 'children': [{'children_name': 'c1'}, {'children_name': 'c2'}]}

Tested on Python3.12 with these packages:

flask-marshmallow      1.2.1
Flask-SQLAlchemy       3.1.1
marshmallow            3.21.3
marshmallow-sqlalchemy 1.0.0
SQLAlchemy             2.0.31

Upvotes: 1

Related Questions