9

我对python相当陌生。我有两个 SQLAlchemy 模型如下:

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()

我有两个棉花糖模式类:

class ListingSchema(Schema):
 id = fields.Int()
 title = fields.Str()
 location_id = fields.Int()

class LocationSchema(Schema):
 id = fields.Int()
 title = fields.Str()

我创建了一个嵌套模式类,例如:

class NestedSchema(Schema):
 listing = fields.Nested(ListingSchema)
 location fields.Nested(LocationSchema)

我正在做这样的连接查询:

listing,location = db.session.query(Listing,Location)\
                            .join(Location, and_(Listing.location_id == Location.id))\
                            .filter(Listing.id == listing_id).first()

数据加载到我检查过的对象中。如何解析这个模式?我试过了

result,errors = nested_listing_Schema(listing,location)

这会产生错误:“列表对象不可迭代。”

4

1 回答 1

13

正确的是使用您创建的 NestedSchema 而不是 nested_schema 的类,这样做:

result,errors = NestedSchema().dump({'listing':listing,'location':location})

结果将是:

dict: {
       u'listing': {u'id': 8, u'title': u'foo'},
       u'location': {u'id': 30, u'title': u'bar'}
      }

但我不明白你为什么要制作“NestedSchema”,我认为你可以用另一种方式来做。

首先,忘记“NestedSchema”类。

之后,更改您的“ListingSchema”,如下所示:

class ListingSchema(Schema):
    id = fields.Int()
    title = fields.Str()
    location_id = fields.Int()
    location = fields.Nested("LocationSchema") #The diff is here

现在你可以这样做:

listing = db.session.query(Listing).get(listing_id) # Suppose listing_id = 8
result,errors = ListingSchema().dump(listing)
print result

结果将是:

dict: {
        u'id': 8, u'title': u'foo', u'location_id': 30, u'location': {u'id': 30, u'title': u'bar'}
      }

请注意,现在,“位置”是“列表”的属性。

而且您仍然可以进行双向嵌套,只需在 Listing (model) 中添加一个 backref 并将 ListingSchema 添加为嵌套在 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

many=True是因为我们有一对多的关系。exclude=("location")就是避免递归异常。

现在我们也可以按位置搜索。

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'},
             ...
             ]
       }

您可以在此处查看有关它的文档

于 2016-09-28T23:08:01.823 回答