2014-03-03 28 views
1

簡單瓶REST API的角度應用我有以下型號:SQL-鍊金術聚集有一個一對一的關係

class User(db.Model, ModelMixin): 
    """ attributes with _ are not exposed with public_view """ 
    __tablename__ = "users" 
    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String(32), unique=True, index=True) 
    _company_id = db.Column(db.Integer, db.ForeignKey("companies.id")) 

class Company(db.Model, ModelMixin): 
    __tablename__ = "companies" 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.Unicode(32)) 
    _employees = db.relationship("User", backref="company", lazy="dynamic") 
    _deal = db.relationship("Deal", backref="company", uselist=False) 

class Deal(db.Model, ModelMixin): 
    __tablename__ = "deals" 
    id = db.Column(db.Integer, primary_key=True) 
    active = db.Column(db.Boolean(), default=True) 
    _company_id = db.Column(db.Integer, db.ForeignKey("companies.id")) 

交易和公司有一對一的關係,公司和用戶都是一個-太多。我試圖確定基本的CRUD操作,並用此格式返回:

deals = [ 
     { 
     "id": 1, 
     "comment": 'This is comment content', 
     "company": { 
      "id": 5, 
      "name": 'Foo', 
      "created_on": '20 Mar 2013', 
     }, 
     "employees": [{ 
      "id": 7, 
      "first_name": 'a', 
      "last_name": 'b', 
      "email": '[email protected]' 
     }, 
     { 
      "id": 8, 
      "first_name": 'A', 
      "last_name": 'B', 
      "email": '[email protected]' 
     }] 
     }, 
     { 
     "id": 2, 
    .... 

現在我正在考慮讓所有有效交易的Deal.query.filter_by(active = True).all()轉換與dict,加公司和員工的查詢,添加,然後返回JSON 。

有沒有更好的生成方式?有了這個解決方案,我需要做n次交易中的n個查詢,並且我不知道如何在SQL-Alchemy中做

+0

如果有與同一家公司的多個交易是你確定要這樣只會工作爲每個人返回公司和員工數據?另一種電線格式可以接受嗎? –

+0

你說得對,我不應該讓這裏的員工回來。我想我應該回到交易清單。打開alt解決方案。 –

+0

我正在[Flask-Presst](https://github.com/biosustain/flask-presst)上工作,這是一個爲這些場景(SQLAlchemy +嵌入)明確設計的REST API庫。這是一項正在進行的工作,但也許您會發現它很有用。我最近還添加了[Angular-Presst](https://github.com/biosustain/angular-presst),這是一個匹配的GitHub的AngularJS庫。 (還有一項工作正在進行中) – lyschoening

回答

2

首先,請閱讀Format of requests and responses文檔。 flask-restless的回覆格式與您的願望不同。

如果您要使用flask-restless,目前無法預加載Deal._company._employees(只能加載第1級關係)。然後

api_manager.create_api(
     Company, collection_name="custom_company", 
     results_per_page = -1, # disable pagination completely 
    ) 

,這樣做:在你的情況,你可以端點在Company雖然註冊,這將同時加載Company._deal以及Company._employees

rv = c.get('/api/custom_company_api', 
     headers={'content-type': 'application/json'}, 
     ) 

將返回類似:

{ 
    "num_results": XXX, 
    "objects": [ 
    { 
     "_deal": { 
     "_company_id": 1, 
     "active": true, 
     "id": 1 
     }, 
     "employees": [ 
     { 
      "_company_id": 1, 
      "id": 1, 
      "username": "User1" 
     }, 
     { 
      "_company_id": 1, 
      "id": 2, 
      "username": "User2" 
     } 
     ], 
     "id": 1, 
     "name": "Company1" 
    }, 
    { 
... 
} 

我相信,在這一點上,你可以用這種方式來擺脫焦慮。如果您要提供自己的自定義端點,則可以在一條SQL聲明中獲取所有數據,並自行轉換爲您所需的格式。 SQLAlchemy的查詢可能是這樣的:

from sqlalchemy.orm import joinedload 
qry = (db.session.query(Deal) 
     .options(
      joinedload(Deal.company). 
      joinedload(Company.employees) 
      ) 
     .filter(Deal.active == True) 
     ) 

但是請注意,如果你的_employees關係不"lazy='dynamic'"