How to handle nested relationships in marshmallow-sqlalchemy
It appears, that one way of handling this is to add an initializer on the sqlalchemy model, which explicitly appends to the collection
class Author(Model):
__tablename__ = "author"
def __init__(self, books=None, *args, **kwargs):
super(Author, self).__init__(*args, **kwargs)
books = books or []
for book in books:
self.books.append(book)
Still curious though if there is a better solution out there.
I was having similar issues to this old post. Managed to fix this post under a slightly different framework Flask + SQLAlchemy + Marshmallow-SQLAlchemy (version 2). Posted code in case helpful.
Most of change are to models.py
- Change of line
books = relationship("Book", back_populates="author")
- Used
back_populates
instead ofbackref
as I was getting errorsqlalchemy.exc.ArgumentError: Error creating backref 'books' on relationship 'Book.author': property of that name exists on mapper 'mapped class Author->author
models.py
class Book(db.Model):
__tablename__ = "book"
id = Column(db.Integer, primary_key=True)
title = Column(db.String(50))
author_id = Column(db.Integer, db.ForeignKey("author.id"), nullable=False)
author = relationship("Author", back_populates="books")
class Author(db.Model):
__tablename__ = "author"
id = Column(db.Integer, primary_key=True)
name = Column(db.String(250))
books = relationship("Book", back_populates="author")
schemas.py - mostly same
class BookSchema(ModelSchema):
class Meta:
model = Book
sqla_session = db.session
class AuthorSchema(ModelSchema):
class Meta:
model = Author
sqla_session = db.session
books = fields.Nested(BookSchema, many=True)
views.py
@api.route('/author/', methods=['POST'])
def new_author():
schema = AuthorSchema()
author = schema.load(request.get_json())
db.session.add(author.data) # version 2 marshmallow
db.session.commit()
return jsonify({"success": True})