Relationships require the input object has a property with the same name
I just created a Schema with the following [simplified] definition :
class UploadSchema(Schema):
class Meta:
type_ = 'upload'
id = fields.String(attribute='upload_id')
path = fields.String()
user = Relationship(
related_view='rest_api.user',
related_view_kwargs={
'user_id': '<user_id>'
},
many=False,
type_='user',
id_field='user_id'
)
This was based off the model definition here:
class Upload(db.Model, CRUDMixin):
__tablename__ = "uploads"
upload_id = Column(Integer, primary_key=True)
path = Column(Unicode)
user_id = Column(Integer, ForeignKey('users.user_id'))
See how, in my SQLAlchemy model, I don't have a user field? Because of the way that serialize() is defined in marshmallow (https://github.com/marshmallow-code/marshmallow/blob/e96bf97656ca3a8299d1382fae26c85f150e7e39/src/marshmallow/fields.py#L301-L306), if the get_value() call returns MISSING, the entire field is skipped, and thus the relationship is not serialized. The problem is, we don't actually need to have an underlying field for the Relationship, it's constructed using the related_kwargs argument, which in my case uses user_id, not user to find the relationship.
I suggest we add a definition for Relationship#serialize() to ensure that it still actually generates the field, even if the value for that field is MISSING.
In my cases, it was an easy workaround to just add an SQLAlchemy relationship() to the underlying Upload model:
class Upload(db.Model, CRUDMixin):
__tablename__ = "uploads"
upload_id = Column(Integer, primary_key=True)
path = Column(Unicode)
user_id = Column(Integer, ForeignKey('users.user_id'))
user = relationship('User', back_populates='uploads')
But if you don't have the benefit of using an ORM that can do this, this problem would be much worse.