2011-11-22 59 views
0

请帮我在SQLAlchemy中建模。用户可以创建一个问题。一个问题可以有多种选择(例如,是,否,之后,可能,不知道,下一年,不适用)。我在问题和选择之间创建了一个映射器。如何在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。我在映射表中没有关系。我希望能够计算给定问题的答案。

回答

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']), 
      ) 

替代(更规范化的DB型)是只定义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')) 

编辑-1:在这种情况下,你可以有一个关系问及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)列。现在


,才能算的响应,你要么添加关系QuestionQuestionResponse之间,并返回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) 
      ) 
+0

非常感谢了详细的答案。我了解了column_property。当我选择第二个答案时,查询变得非常困难,因为我需要一个带选项和列表的联接。 – Bharad

+0

例如,我可以通过question_choice_id查询QuestionReponse,如何从这里获得选择?我无法将关系添加到question_choices映射表中。 – Bharad

+0

我在回答中添加了“answers”关系配置。 – van