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)
)