Как я могу получить совпадающие записи, которые являются множественными отношениями, кроме SQLAlchemy? - PullRequest
2 голосов
/ 17 мая 2019

У меня есть четыре таблицы / классы: Group. Bank, Question и Survey. В опросах много вопросов, вопросы принадлежат банку, который, в свою очередь, принадлежит группе. У меня есть группа и опрос (я использую метод экземпляра Survey и проверяю все экземпляры Group) и хочу знать, какие вопросы принадлежат обоим.

class Group(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    banks = db.relationship('Bank', backref='group')


class Bank(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    group_id = db.Column(db.Integer, db.ForeignKey('group.id')
    questions = db.relationship('Question', backref='bank', lazy='dynamic')


class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    survey_id = db.Column(db.Integer, db.ForeignKey('survey.id')
    bank_id = db.Column(db.Integer, db.ForeignKey('bank.id')


class Survey(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    questions = db.relationship('Question', backref='survey', lazy='dynamic')

Я думал о том, чтобы попробовать что-то вроде self.questions.filter(Question.bank.in_(group.banks)) (self - экземпляр Survey), но получил NotImplementedError. Прямо сейчас я использую некрасивые вложенные циклы for с условиями if и пытаюсь их очистить, тем более что я ожидаю, что из-за увеличения числа опросов и вопросов возникнет проблема со скоростью.

for group in groups:
    for bank in group.banks:
      for question in bank.questions:
          if question in self.questions:
              # do stuff

1 Ответ

1 голос
/ 18 мая 2019

Вы можете использовать объединения , чтобы пройти через отношения и получить необходимую информацию.

Этот запрос присоединяет таблицу опроса к банковской таблице на их общем ключе идентификатора внешнего вопроса, а затем присоединяет банковскую таблицу к групповой таблице.

q = (session.query(Survey.id, Question.id, Group.id)
            .join(Survey.questions, Bank)
            .join(Group)
            .filter(Survey.id == self.id)
            .all())

Чтобы получить информацию для всех опросов в одном запросе, удалите предложение filter.

SQL, сгенерированный запросом, является

SELECT survey.id AS survey_id, question.id AS question_id, "group".id AS group_id                                                                                                                
    FROM survey 
        JOIN question ON survey.id = question.survey_id 
        JOIN bank ON bank.id = question.bank_id 
        JOIN "group" ON "group".id = bank.group_id                                                                                                                          
    WHERE survey.id = ? 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...