Как вложить много-много объектов в Python? - PullRequest
0 голосов
/ 07 февраля 2019

Я выбираю данные из БД из 3 разных таблиц, и мне нужно вернуть их все как 1 объект с другими вложенными объектами внутри.

В частности, у меня есть объект ApplicationForm, который содержит от 1 до многихРаздел объектов.Объекты Section, в свою очередь, могут содержать от 1 до многих объектов Question.

Я успешно сопоставил раздел с ApplicationForm, но у меня возникли проблемы с объектами Question, поскольку их необходимо сопоставить с правильными разделами на основев их атрибуте section_id.

class ApplicationFormAPI(ApplicationFormMixin, restful.Resource):

    question_fields = {
      'id': fields.Integer,
      'type': fields.String,
      'description': fields.String,
      'order': fields.Integer
    } 

    section_fields = {
      'id': fields.Integer,
      'name': fields.String,
      'description': fields.String,
      'order': fields.Integer,  
      'questions': fields.List(fields.Nested(question_fields))   
    }

    form_fields = {
      'id': fields.Integer,
      'event_id': fields.Integer,
      'is_open':  fields.Boolean,
      'deadline': fields.DateTime,
      'sections': fields.List(fields.Nested(section_fields)) 
    }

    @marshal_with(form_fields)
    def get(self):
        req_parser = reqparse.RequestParser()
        req_parser.add_argument('event_id', type=int, required=True, help = 'Invalid event_id requested. Event_id\'s should be of type int.')
        args = req_parser.parse_args()

        form = db.session.query(ApplicationForm).filter(ApplicationForm.event_id == args['event_id']).first()     
        sections = db.session.query(Section).filter(Section.application_form_id == form.id)   #All sections in our form
        questions = db.session.query(Question).filter(Question.application_form_id == form.id) #All questions in our form        

        form.sections = sections

        #Need to bind the sections with their relevant questions 
        for s in form.sections:
            sec_questions = []
            for q in questions:
                if(q.section_id == s.id):
                    sec_questions.append(q)
            s.questions = sec_questions

        if form: 
            return form
        else: 
            return EVENT_NOT_FOUND

Я возвращаю вопросы как "нулевые" в моем объекте ответа.

{
    "deadline": "Sun, 24 Mar 2019 00:00:00 -0000", 
    "event_id": 1, 
    "id": 1, 
    "is_open": true, 
    "sections": [
        {
            "description": "Personal biographical info", 
            "id": 1, 
            "name": "Personal Details", 
            "order": 1, 
            "questions": null
        }, 
        {
            "description": "What do you do", 
            "id": 2, 
            "name": "Career Info", 
            "order": 2, 
            "questions": null
        }, 
        {
            "description": "Everything else", 
            "id": 3, 
            "name": "Misc Info", 
            "order": 3, 
            "questions": null
        }
    ]
}

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Я решил проблему, добавив .all () в конец моего раздела и запросов:

    sections = db.session.query(Section).filter(Section.application_form_id == form.id).all()   #All sections in our form
    questions = db.session.query(Question).filter(Question.application_form_id == form.id).all() #All questions in our form        

Не совсем уверен, почему это решило проблему, но это произошло.

0 голосов
/ 07 февраля 2019

Эта строка не кажется правильной.Вопросы вложены в поле ваших разделов, и вы ссылаетесь на идентификатор формы, который может привести к пустым запросам или ложным данным.

questions = db.session.query(Question).filter(Question.application_form_id == form.id)

Если это не проблема, вы можете попробовать выполнить другой запрос, находясь в новомитерация раздела.Итак:

questions = db.session.query(Question).filter(Question.id == s.id)

Это помогает иметь меньше if, но увеличивает нагрузку на базу данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...