简体   繁体   English

将两条 sqlalchemy 语句合二为一

[英]Combine two sqlalchemy statements into one

I want to retrieve from my DB a single record, which is a question (I am building a quiz mechanism).我想从我的数据库中检索一条记录,这是一个问题(我正在构建一个测验机制)。 I have the following requirements to this hit:我对此命中有以下要求:

  1. It should be a question from the quiz the user is currently playing这应该是用户当前正在玩的测验中的问题
  2. It should be a question which the user has not answered before, eg;它应该是用户以前没有回答过的问题,例如; it should not be a record in the responses table它不应该是响应表中的记录
  3. The questions should be ordered by category.问题应按类别排序。

The following models are involved:涉及以下模型:

Questions: Contains all questions from all quizzes问题:包含所有测验的所有问题

class Questions(db.Model):
# table name
__tablename__ = "questions"

id = db.Column(db.Integer, primary_key=True)
quiz_id = db.Column(db.Integer, ForeignKey("quizzes.id"))
text = db.Column(db.String(80))
category = db.Column(db.Integer)
type = db.Column(db.String(80))

Responses:Contains all responses回复:包含所有回复

class Responses(db.Model):
# table name
__tablename__ = "responses"

id = db.Column(db.Integer, primary_key=True)
session_id = db.Column(db.Integer, ForeignKey("sessions.id"))
question_id = db.Column(db.Integer, ForeignKey("questions.id"))
option_id = db.Column(db.Integer, ForeignKey("options.id"))
answer = db.Column(db.String(80), nullable=True)

Responses: When a user starts a quiz, a session is started.响应:当用户开始测验时,会话开始。 This sessions relates to the quiz being played in order to be able to collect the question, and store and relate the responses to a user.该会话与正在播放的测验相关,以便能够收集问题,并存储和关联对用户的响应。

class Sessions(db.Model):
__tablename__ = "sessions"

id = db.Column(db.Integer, primary_key=True)
quiz_id = db.Column(db.Integer, ForeignKey("quizzes.id"))
user_id = db.Column(db.Integer, ForeignKey("users.id"))e here

For the first and third requirement I have written to following code:对于第一个和第三个要求,我写了以下代码:

question = Questions.query.filter(Questions.quiz_id == quiz.id).order_by(Questions.category).first()

This works in the sense that it returns the questions in te correct order这在某种意义上是有效的,它以正确的顺序返回问题

For the second requirement I have written the following:对于第二个要求,我写了以下内容:

    check = Responses.query.filter(Responses.session_id == session[0].id,
                                   Responses.question_id == question.id).scalar() is not None

Next I attempted to create one query, but this was not succesfull.接下来我尝试创建一个查询,但这并不成功。 See below code:见下面的代码:

question = db.session.query(Questions, Responses).filter(Questions.quiz_id == quiz.id).filter(
        Responses.session_id == session[0].id, Responses.question_id == Questions.id).order_by(Questions.category).scalar() is None
    

The result was it actually only gave me questions which were already answered, instead of unanswered.结果是它实际上只给了我已经回答的问题,而不是未回答的问题。 I am also not sure it's going to filter on the correct question_id already.我也不确定它是否会过滤正确的 question_id。

EDIT: I think I know have the correct SQL call编辑:我想我知道有正确的 SQL 调用

SELECT * FROM quiz.questions JOIN quiz.quizzes ON quiz.questions.quiz_id = quiz.quizzes.id WHERE quiz.quizzes.year = 2020 AND quiz.questions.id NOT IN (SELECT question_id FROM quiz.responses WHERE quiz.responses.session_id = 11 ) ORDER BY quiz.questions.category ASC;

You can use except to combine two queries;您可以使用except来组合两个查询; this will run both queries, and exclude the results of the second query (ie query1 questions - query2 questions):这将运行两个查询,并排除第二个查询的结果(即 query1 问题 - query2 问题):

For example:例如:

# get questions from the current quiz
Questions.query.filter(Questions.quiz_id == quiz.id).\
except(
  # except for questions with a response in the current session 
  Questions.query.filter(
    Questions.quiz_id == quiz.id,
    Questions.id == Responses.question_id,
    Responses.session_id == session[0].id
  )
).order_by(Questions.category).first()

In the end, this was the solution:最后,这是解决方案:

        question = Questions.query\
        .filter(Questions.quiz_id == quiz.id) \
        .filter(Responses.session_id == session[0].id) \
        .filter(Responses.question_id != Questions.id) \
        .order_by(Questions.category) \
        .order_by(func.rand()) \
        .first()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM