SQLAlchemy / Flask - получает количество строк в таблице отношений

Вот мой сценарий. У меня есть стол Books в каждой книге есть таблица Questions и каждый вопрос имеет таблицу Answers,

То, что я хочу сделать, это эффективно получить количество ответов для данного списка Question.id, Пример:

# 6,000 Question.id's for Book.id == 1
questions = [0, 1, 2, 3, 4, 5, 6, ..., 6000]

Вот что я делаю, и это оказывается очень очень неэффективным:

# This takes a couple minutes for it to finish
count = 0
query = QuestionModel.query.filter(QuestionModel.id.in_(questions)).all()

for q in query:
  count += len(list(q.Answers))

# count = 3456

Я предполагаю, что это так медленно, потому что q.Answers на самом деле наполняется данными.

Вот мои модели:

class BookModel(db.base):
    __tablename__ = 'books_book'
    __table_args__ = {
        'autoload': True,
        'extend_existing': True,
        'autoload_with': db.instance.engine,
    }
    id = Column(Integer, primary_key=True)
    Chapters = relationship(ChapterModel)
    QuestionMeta = relationship(QuestionMetaModel)

class QuestionMetaModel(db.base):
    __tablename__ = 'questions_questionmeta'
    __table_args__ = {
        'autoload': True,
        'extend_existing': True,
        'autoload_with': db.instance.engine,
    }
    id = Column(Integer, primary_key=True)
    question_id = Column(ForeignKey('questions_question.id'))
    book_id = Column(ForeignKey('books_book.id'))
    chapter_id = Column(ForeignKey('books_chapter.id'))

class QuestionModel(db.base):
    __tablename__ = 'questions_question'
    __table_args__ = {
        'autoload': True,
        'extend_existing': True,
        'autoload_with': db.instance.engine,
    }
    id = Column(Integer, primary_key=True)
    Answers = relationship(AnswerModel)

class AnswerModel(db.base):
    __tablename__ = 'answers_answer'
    __table_args__ = {
        'autoload': True,
        'extend_existing': True,
        'autoload_with': db.instance.engine,
    }
    id = Column(Integer, primary_key=True)
    question_id = Column(ForeignKey('questions_question.id'))

Вопрос: все, что я хочу, это количество записей в QuestionModel.Answers не сами данные. Как бы это сделать, чтобы это не заняло 2 минуты? Book.id? Хватая Question.id для каждой книги быстро, но захватывая количество ответов для каждой Question.id очень медленно

1 ответ

Выполнить join через BookModel, QuestionModel, а также AnswerModel и использовать SQLAlchemy func.count,

from sqlalchemy import func

count_query = (session.query(BookModel, QuestionModel, AnswerModel, func.count(AnswerModel.id))
    .select_from(AnswerModel)
    .join(QuestionModel)
    .join(BookModel)
    .group_by(BookModel)
)
Другие вопросы по тегам