Ваш маппер для QuestionResponse
уже довольно хорош, но он не ограничивает ответ на выбор, который не настроен: поэтому, если LATER
не разрешен ответ на вопрос Will you marry me?
, база данных не ограничиваетэтот.
Одним из решений было бы также добавить ограничение внешнего ключа из двух столбцов в QuestionResponse
:
class QuestionResponse(Base):
"""A friend's response to a question"""
__tablename__ = 'question_responses'
id = Column(Integer, primary_key=True)
question_id = Column(Integer, ForeignKey('questions.id'))
choice_id = Column(Integer, ForeignKey('choices.id'))
# ...
__table_args__ = (
ForeignKeyConstraint(['question_id', 'choice_id'], ['question_choices.question_id', 'question_choices.choice_id']),
)
Альтернатива (более нормализованная)Модель БД) предназначена для определения FK только для question_choices.id
:
class QuestionResponse(Base):
"""A friend's response to a question"""
__tablename__ = 'question_responses'
id = Column(Integer, primary_key=True)
question_choice_id = Column(Integer, ForeignKey('question_choices.id'))
edit-1 : в этом случае вы можете задать связь между Question и QuestionResponseкак показано ниже, который также предоставит вам счет:
class Question(Base):
# ....
answers = relationship("QuestionResponse",
primaryjoin="Question.id==question_choices.c.question_id",
secondary=question_choices,
secondaryjoin="question_choices.c.id==QuestionResponse.question_choice_id",
backref="question",
)
В любом случае вы можете добавить UniqueConstraint
к таблице question_choices
в столбцах (question_id, choice_id)
.
Теперь для подсчета ответов вы либо добавляете связь между Question
и QuestionResponse
и возвращаете len(answers)
, либо просто создаете свойство на основе запроса в Question
:
class Question(Base):
# ...
answer_count = column_property(
select([func.count(QuestionResponse.__table__.c.id)]).
where(question_choices.c.question_id==id).
where(question_choices.c.id==QuestionResponse.__table__.c.question_choice_id)
)