2011-11-22 54 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