请帮我在SQLAlchemy中对此进行建模。用户可以创建问题。一个问题可以有多种选择(例如,是,不,以后,可能,不知道,下一年,不适用)。我在问题和选择之间创建了一个映射器。如何在SQLAlchemy中建模响应?
question_choices = Table('question_choices', Base.metadata,
Column('id', Integer, primary_key=True),
Column('question_id', Integer, ForeignKey('questions.id')),
Column('choice_id', Integer, ForeignKey('choices.id'))
)
class Choice(Base):
__tablename__ = 'choices'
id = Column(Integer, primary_key=True)
value = Column(String(30), nullable=False)
class Question(Base):
__tablename__ = 'questions'
id = Column(Integer, primary_key=True)
title = Column(String(100))
created = Column(DateTime)
choices = relationship('Choice', secondary=question_choices)
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'))
user_id = Column(Integer, ForeignKey('users.id'))
created = Column(DateTime)
questionResponse模型未规范化。 Question_id和listing_id重复出现。我在mapper表中没有关系。我希望能够计算给定问题的答案。
答案 0 :(得分:1)
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)
)