Question

In simple Flask REST api for angular app I've got following models:

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

Deal and Company have one to one relationship and Company and Users are one-to-many. I'm trying to define basic CRUD operations and return in this format:

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": 'ab@b.com'
         },
         {
           "id": 8,
           "first_name": 'A',
           "last_name": 'B',
           "email": 'A@ghgg.com'
         }]
       },
       {
         "id": 2,
     ....

Right now I'm thinking of getting all active deals Deal.query.filter_by(active = True).all() convert to dict, add company and query employees and add it, then return json.

Is there a better way of generating? With this solution I need to make n queries per n deals and I don't know how to do in SQL-Alchemy

No correct solution

OTHER TIPS

First, please read Format of requests and responses documentation. The format of the response of flask-restless is different from what you desire.

If you were to use flask-restless, currently it is not possible to preload Deal._company._employees (only level 1 relationships can be loaded). In your case you could register endpoint at Company though, which will load both Company._deal as well as Company._employees:

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

then, doing:

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

will return something like:

{
  "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"
    },
    {
...
}

I believe, this is all you can with flask-restless at this point. In case you were to provide your own custom endpoint, then you can get all the data in one SQL statement and convert to your desired format on your own. sqlalchemy query might look like this:

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

Note, however, that this will only work if your _employees relationship is not "lazy='dynamic'"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top