I have a project where I'm trying to load data from JSON into a Sqlalchemy database using the marshmallow-sqlalchemy package. The model contains a one-to-many relationship with a child model.
Using the classic example of an author with many books:
class Book(Base):
__tablename__ = "book"
id = Column(Integer, primary_key=True)
title = Column(String(50))
author_id = Column(Integer, ForeignKey("author.id"), nullable=False)
author = relationship("Author", backref=backref("books"))
class Author(Base):
__tablename__ = "author"
id = Column(Integer, primary_key=True)
name = Column(String(250))
books = relationship("Author", back_populates="author")
class BookSchema(ModelSchema):
class Meta:
model = Book
sqla_session = Session
class AuthorSchema(ModelSchema):
class Meta:
model = Author
sqla_session = Session
books = fields.Nested(BookSchema, many=True)
And the input JSON is
{
"name": "Author A",
"books": [
{"title": "Book 1"},
{"title": "Book 2"}
]
}
When I try to load that JSON, using the following:
json_repr = {...}
author_schema = AuthorSchema()
obj_repr = author_schema.load(json_repr)
It is raising an exception when it trys to deserialize the document saying that Book is an unhashable type.
What is happening, I believe is that the deserializer is trying to create the objects using something like
obj = model(**data)
which won't work with a one-to-many relationship, since the instances of the list need to be append()
'ed to the Author.books property.
I've been unable to find any examples of this working anywhere on the web, Every example I've seen seems to be nesting a single instance, not a list. Is there a recommended way of accomplishing this using marshmallow-sqlalchemy, or should I revert back to using the straight marshmallow package, and manually appending the relationship objects using @post_load methods.