I am using sqlalchemy and marshmallow in my RESTful flask application to serialize my models. I have a hybrid_property that comes from one of my relationships on that model. I would like to now serialize that hybrid_property in my schema using the schema from the related model.
Has anyone done this before? Here are my relevant pieces of code. It doesn't seem to be including the last_assessment
in the serialized version of the model when I check the response
class Person(db.Model):
daily_rula_average_ranges = db.relationship('DailyRulaAverageRange', order_by="DailyRulaAverageRange.date", back_populates='person')
@hybrid_property
def last_assessment(self):
if self.daily_rula_average_ranges.length > 0:
return self.daily_rula_average_ranges[-1]
class PersonSchema(ma.Schema):
last_assessment = ma.Nested(DailyRulaAverageRangeSchema, only=['id', 'date', 'risk'])
class Meta:
fields = ('last_assessment')
It's a bit sneaky, but I believe the problem is that the line if self.daily_rula_average_ranges.length > 0:
is causing an AttributeError to be raised, because length is not usually an attribute of lists. You probably meant if len(self.daily_rula_average_ranges) > 0:
.
Here's an ORM-agnostic example - the serializer returns no field if an attribute error is raised, but returns data fine if appropriate data is returned by the property:
from marshmallow import fields, Schema
from marshmallow.fields import Nested
class DailyRulaAverageRangeSchema(Schema):
id=fields.UUID()
date=fields.Date()
risk=fields.Integer()
class PersonSchema(Schema):
last_assessment = Nested(DailyRulaAverageRangeSchema, only=['id', 'date', 'risk'])
class Meta:
fields = ('last_assessment',)
class Person(object):
@property
def last_assessment(self):
raise AttributeError('oops')
PersonSchema().dump(Person())
# Out[73]: {}
class Person(object):
@property
def last_assessment(self):
return {"id": None, "date":None, 'risk': 100}
PersonSchema().dump(Person())
# Out[83]: {u'last_assessment': {u'date': None, u'id': None, u'risk': 100}}
It is not too surprising that marshmallow behaves this way because an attribute that raises an AttributeError will appear as though the attribute does not exist, e.g.:
class Person(object):
@property
def last_assessment(self):
raise AttributeError('oops')
hasattr(Person(), 'last_assessment')
# Out: False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With