2

Currently I have a bunch of tables with clear relationships set up. However, I want one table (Application) that has a relationship to an Answer table and a Question table to only show answers that have Questions that are marked as active. I'm trying to do this via the Application model so that in Marshmallow it can return inside of application. I'm also trying to do this without producing an N+1 query.

Tables

application_question_table = db.Table(
    'application_questions',
    db.Column(
        'application_id',
        db.Integer,
        db.ForeignKey(
            'application.id',
            name="application_questions_application_id_fkey",
            ondelete="CASCADE"
        )
    ),
    db.Column(
        'question_id',
        db.Integer,
    db.ForeignKey(
            'question.id', 
            name="application_questions_question_id_fkey",
            ondelete="CASCADE"
        )
    )
)

class Application(Base):
    id = db.Column(db.Integer, primary_key=True)
    answers = db.relationship('Answer', back_populates="application", cascade=‘delete)
    active_answers = db.relationship("should only show answerswhere question is active")
    questions = db.relationship('Question', lazy="dynamic", secondary=application_question_table)


class Answer(Base):
    id = db.Column(db.Integer, primary_key=True)
    question_id = db.Column(db.Integer, db.ForeignKey('question.id', ondelete="SET NULL", name="answer_question_id_fkey"))
    question = db.relationship('Question', back_populates=“answers")


class Question(Base):
    id = db.Column(db.Integer, primary_key=True)
    answers = db.relationship("Answer", back_populates="question")
    applications = db.relationship('Application',lazy="dynamic", secondary=application_question_table)
    active = db.Column(db.Boolean, default=True)

Schema - Note the get visible questions is essentially what i want to happen. But i don't like doing it this way because it'll be an additional query for every single application i find.

class ApplicationSchema(ModelSchema):
    visible_answers = fields.Method('get_visible_answers')
    class Meta:
        model = Application

    def get_visible_answers(self, application):
        schema = ApplicationAnswerSchema(many=True)
        answers = Answer.query.join(
            Answer.application,
            Answer.question
        ).filter(
            Application.id == application.id,
            Question.active == True,
        ).all()
        return schema.dump(answers).data


class ApplicationAnswerSchema(ModelSchema):

    class Meta:
        model = Answer

My expected behavior is when I do something like

applications = Application.query.options(joinedload(Application.active_answers)).all()
schema = ApplicationSchema(many=True)
results = schema.dump(applications)

That there will only be one query and I can key into every application and get the visible answers.

The actual result i'm getting is that i'm getting an additional query emitted for every application.

LittleBro
  • 61
  • 1
  • 5

0 Answers0