2014-02-26 49 views
12

我有一個問題關於燒瓶寧靜延伸。我剛剛開始使用它並面臨一個問題。我有flask-sqlalchemy連接多對一關係的實體,我希望那個安靜的終端返回父實體及其所有孩子在json使用編組。在我的情況下,Set包含許多參數。我看着燒瓶寧靜docs,但沒有任何解釋如何解決這個案件。燒瓶寧靜:元帥複雜的對象json

好像我錯過了一些明顯的東西,但找不到任何解決方案。 這裏是我的代碼:

# entities 
class Set(db.Model): 
    id = db.Column("id", db.Integer, db.Sequence("set_id_seq"), primary_key=True) 
    title = db.Column("title", db.String(256)) 

    parameters = db.relationship("Parameters", backref="set", cascade="all") 


class Parameters(db.Model): 
    id = db.Column("id", db.Integer, db.Sequence("parameter_id_seq"), primary_key=True) 
    flag = db.Column("flag", db.String(256)) 
    value = db.Column("value", db.String(256)) 
    set_id = db.Column("set_id", db.Integer, db.ForeignKey("set.id")) 


# marshallers 

from flask.ext.restful import fields 

parameter_marshaller = { 
    "flag": fields.String, 
    "value": fields.String 
} 

set_marshaller = { 
    'id': fields.String, 
    'title': fields.String, 
    'parameters': fields.List(fields.Nested(parameter_marshaller)) 
} 

# endpoint  

class SetApi(Resource): 

    @marshal_with(marshallers.set_marshaller) 
    def get(self, set_id): 
     entity = Set.query.get(set_id) 
     return entity 


restful_api = Api(app) 
restful_api.add_resource(SetApi, "/api/set/<int:set_id>") 

現在,當我打電話/api/set/1我得到服務器錯誤:

TypeError: 'Set' object is unsubscriptable

所以我需要一種方法來正確地定義set_marshaller端點返回該JSON:

{ 
    "id": : "1", 
    "title": "any-title", 
    "parameters": [ 
     {"flag": "any-flag", "value": "any-value" }, 
     {"flag": "any-flag", "value": "any-value" }, 
     ..... 
    ] 
} 

我很感激任何幫助。

回答

20

我自己找到了解決這個問題的辦法。

flask-restful玩弄後,我發現,我犯了幾個錯誤:

首先set_marshaller應該是這樣的:

blob_marshaller = { 
    'id': fields.String, 
    'title': fields.String, 
    'parameters': fields.Nested(parameter_marshaller) 
} 

不寧編組如果參數列表,乘警json列表可以處理情況。

的另一個問題是,在API的參數設置有延遲加載,所以當我嘗試馬歇爾集我得到KeyError: 'parameters',所以我需要顯式地加載參數如下:

class SetApi(Resource): 

    @marshal_with(marshallers.set_marshaller) 
    def get(self, set_id): 
     entity = Set.query.get(set_id) 
     entity.parameters # loads parameters from db 
     return entity 

或者另一種選擇是改變模型關係:

parameters = db.relationship("Parameters", backref="set", cascade="all" lazy="joined") 
+0

非常感謝! – Nils

6

這是一個除的answerZygimantas

我正在使用Flask-RESTful,這是加載嵌套屬性的解決方案。

你可以通過一個調用到元帥裝飾:

class OrgsController(Resource): 
    @marshal_with(Organization.__json__()) 
    def get(self): 
     return g.user.member.orgs 

然後更新模型返回資源領域爲自己的實體。因此嵌套實體會相對返回其實體的資源域。

class Organization(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    ... 

    @staticmethod 
    def __json__(group=None): 
     _json = { 
      'id': fields.String, 
      'login': fields.String, 
      'description': fields.String, 
      'avatar_url': fields.String, 
      'paid': fields.Boolean, 
     } 

     if group == 'flat': 
      return _json 

     from app.models import Repository 
     _json['repos'] = fields.Nested(Repository.__json__('flat')) 

     return _json 

class Repository(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    owner_id = db.Column(db.Integer, db.ForeignKey('organization.id')) 
    owner = db.relationship('Organization', lazy='select', backref=db.backref('repos', lazy='select'), foreign_keys=[owner_id]) 
    ... 

    @staticmethod 
    def __json__(group=None): 
     _json = { 
      'id': fields.String, 
      'name': fields.String, 
      'updated_at': fields.DateTime(dt_format='iso8601'), 
     } 

     if group == 'flat': 
      return _json 

     from app.models import Organization 
     _json['owner'] = fields.Nested(Organization.__json__('flat')) 

     return _json 

這使我在尋找,並履行延遲加載表示:

[ 
    { 
     "avatar_url": "https://avatars.githubusercontent.com/u/18945?v=3", 
     "description": "lorem ipsum.", 
     "id": "1805", 
     "login": "foobar", 
     "paid": false, 
     "repos": 
      [ 
       { 
        "id": "9813", 
        "name": "barbaz", 
        "updated_at": "2014-01-23T13:51:30" 
       }, 
       { 
        "id": "12860", 
        "name": "bazbar", 
        "updated_at": "2015-04-17T11:06:36" 
       } 
      ] 
    } 
] 

我喜歡

1)這種方法是如何讓我來定義每個實體資源我的領域它可以通過應用程序的所有資源路線。

2)團體論點如何讓我自定義表達,但我希望。我在這裏只有'平坦',但是任何邏輯都可以寫入並傳遞給更深的嵌套對象。

3)實體僅在必要時加載。