I am fairly new to python. I have two SQLAlchemy models as follows:
class listing(db.Model):
id = db.Integer(primary_key=True)
title = db.String()
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
location = db.relationship('Location', lazy='joined')
class location(db.Model):
id = db.Integer(primary_key=True)
title = db.String()
I have two Marshmallow schema classes for them:
class ListingSchema(Schema):
id = fields.Int()
title = fields.Str()
location_id = fields.Int()
class LocationSchema(Schema):
id = fields.Int()
title = fields.Str()
I have created a nested schema class like:
class NestedSchema(Schema):
listing = fields.Nested(ListingSchema)
location fields.Nested(LocationSchema)
I am doing the join query like :
listing,location = db.session.query(Listing,Location)\
.join(Location, and_(Listing.location_id == Location.id))\
.filter(Listing.id == listing_id).first()
data gets load in the objects i have checked. How can parse this schema? I have tried
result,errors = nested_listing_Schema(listing,location)
This gives error: "Listing object is not iteratable."
The right is to use the class that you created NestedSchema and not nested_schema, do this:
result,errors = NestedSchema().dump({'listing':listing,'location':location})
And the result wiil be:
dict: {
u'listing': {u'id': 8, u'title': u'foo'},
u'location': {u'id': 30, u'title': u'bar'}
}
But i do not understand why you wanted to make a "NestedSchema", i think you can do it another way.
First, forget the class "NestedSchema".
After, change your "ListingSchema", like this:
class ListingSchema(Schema):
id = fields.Int()
title = fields.Str()
location_id = fields.Int()
location = fields.Nested("LocationSchema") #The diff is here
And now you can do:
listing = db.session.query(Listing).get(listing_id) # Suppose listing_id = 8
result,errors = ListingSchema().dump(listing)
print result
The result will be:
dict: {
u'id': 8, u'title': u'foo', u'location_id': 30, u'location': {u'id': 30, u'title': u'bar'}
}
Note that now, "location" is a property of "listing".
And you can still make a Two-Way Nesting, just add a backref in Listing (model) and add ListingSchema as nested in LocationSchema
class Listing(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(45), nullable=False)
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
location = db.relationship('Location', lazy='joined', backref="listings") #the diff is here
class LocationSchema(Schema):
id = fields.Int()
title = fields.Str()
listings = fields.Nested("ListingSchema", many=True, exclude=("location",)) #The property name is the same as in bakcref
The many=True
is because we have a relationship One-to-Many.
The exclude=("location")
is to avoid recursion exception.
Now we can search by location too.
location = db.session.query(Location).get(location_id) # Suppose location_id = 30
result,errors = LocationSchema().dump(location)
print result
dict: {u'id': 30, u'title': u'bar',
u'listings': [
{u'location_id': 30, u'id': 8, u'title': u'foo'},
{u'location_id': 30, u'id': 9, u'title': u'foo bar baz'},
...
]
}
You can see the docs about it here
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