Flask-SQLAlchemy и Flask-Restless не получают внуков

Проблема

Я создаю приложение на Flask, Flask-SQLAlchemy и Flask-Restless. Я использовал restless для создания API для отношений родитель-потомок-внук*. GET для моего ребенка будет правильно получать внука, но GET для родителя не будет получать внука для каждого ребенка.

* На самом деле отношения родитель-потомок — это отношения «многие ко многим», но с той же предпосылкой.

Модели

class Grandchild(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False)

    parent = db.relationship('Child', backref='grandchild')

parent_child = db.Table('parent_child', 
    db.Column('parent_id', db.Integer, db.ForeignKey('parent.id')),
    db.Column('child_id', db.Integer, db.ForeignKey('child.id')),
    db.Column('number', db.SmallInteger)
)

class Child(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False)

    grandchild_id = db.Column(db.Integer, db.ForeignKey('grandchild.id'), nullable=False)

class Parent(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False)

    children = db.relationship('Child', secondary=parent_child)

api.create_api(Child, exclude_columns=['grandchild_id'])
api.create_api(Parent)

ПОЛУЧИТЬ: /api/дочерний ответ

{
  "num_results": 1, 
  "objects": [
    {
      "id": 1, 
      "name": "test"
      "grandchild": {
        "id": 1, 
        "name": "test"
      }
    }
  ], 
  "page": 1, 
  "total_pages": 1
}

ПОЛУЧИТЬ: /api/родительский ответ

{
  "num_results": 1, 
  "objects": [
    {
      "children": [
        {
          "id": 1, 
          "name": "test", 
          "grandchild_id": 1
        }
      ],
      "id": 1, 
      "name": "test"
    }], 
  "page": 1, 
  "total_pages": 1
}

person Matthew James Davis    schedule 28.03.2014    source источник


Ответы (2)


постпроцессоры могут использоваться для получения внука.

def parent_post_get_many(result=None, search_params=None, **kw):
   for object in result['objects']:
      for child in object['children']:
         grandchild = Grandchild.query.get(child['grand_child_id'])
         child.update({'grandchild': grandchild})

api.create_api(Parent, postprocessors={'GET_MANY': [parent_post_get_many]})
person ramavarsh    schedule 08.10.2014
comment
Кажется, это включает экземпляр модели в структуру данных, а не сериализованный экземпляр, что приводит к ошибке сериализатора JSON. Глядя на внутренности Restless, кажется, что функция сериализации - это serializer() в экземпляре API. Вы знаете, можно ли получить к нему доступ для сериализации экземпляра? - person Andrew Hows; 21.12.2016

Посмотрев на это несколько часов, я собираюсь дать лучший ответ, который у меня есть на данный момент. Я испробовал несколько подходов и не смог ничего добиться для успешного рендеринга внука, поэтому я обратился к трекеру проблем с flask-restless, чтобы посмотреть, что я могу найти:

https://github.com/jfinkels/flask-restless/pull/222#issuecomment-31326359 и ответ @jfinkels, кажется, указывают на то, что то, что вы хотите, в настоящее время не возможно в flask-restless.

Предполагая, что моя оценка состояния проблем верна, вы можете захотеть изучить либо проектирование вокруг этой проблемы, либо использование другого пакета для обслуживания вашего API (возможно, Flask-restful, хотя я признаю, что не использовал его и не не знаю, подходит ли).

FWIW, я использовал Flask-Classy для создания json API для проекта, над которым я работаю. на. Этот процесс немного сложнее, чем я подозреваю, вы хотите, но он также предоставляет достаточную свободу, чтобы лучше контролировать, какие запросы используются и как сериализуются результаты.

person abathur    schedule 09.04.2014
comment
Я пришел к тому же выводу, что и вы, и начал использовать Flask-Restful. У него есть свои проблемы, но, кажется, он дает гораздо больше контроля, чем Flask-Restless, поэтому я продвигаюсь вперед с ним. Я не совсем понимаю проблему, которую решает Flask-Classy. Похоже, это довольно расширяемый инструмент для создания чрезвычайно простого REST API. Там нет упоминания о запросах, ORM и прочем. - person Matthew James Davis; 09.04.2014
comment
Правильно — потребуется гораздо больше работы, чтобы получить то, что, как я думаю, вам нужно от Flask-Classy. Я просто предупреждал вас о его существовании на случай, если вы исчерпаете возможности получения того, что вам нужно, из пакетов, предназначенных для предоставления REST API с минимальным вмешательством. - person abathur; 09.04.2014