0

我有一個名爲Post的模型,它有一個名爲is_answer的布爾字段。如果Postis_answer字段爲真,這是一個「問題」;否則,這是一個「答案」。我想創建下面的問答關係:如何在Flask-SQLAlchemy中創建一個自引用的一對多關係?

一個「問題」可能有很多「答案」,但是一個「答案」只有一個「問題」。由於「問題」和「答案」基本上都是Post,我認爲這種關係必須是自我參照。

這裏是我試過:

class Post(db.Model): 
    __tablename__ = 'posts' 
    id = db.Column(db.Integer, primary_key=True) 
    is_question = db.Column(db.Boolean) 
    post_id = db.Column(db.Integer, db.ForeignKey('posts.id')) 
    question = db.relationship('Post', backref=db.backref('answer', lazy='dynamic'), uselist=False, lazy='dynamic') 

的錯誤是:

ArgumentError: Post.question and back-reference Post.answer are both of the same direction symbol('ONETOMANY'). Did you mean to set remote_side on the many-to-one side ?

回答

2

您需要添加remote_side參數來創建自引用關係。有關documentaion的更多信息。

更新:順便說一下,我認爲你不需要布爾標誌is_question,因爲你可以通過檢查post_id字段是否爲Null來確定問題和答案。

class Post(Base): 
    __tablename__ = 'posts' 
    id = Column(Integer, primary_key=True) 
    post_id = Column(Integer, ForeignKey('posts.id')) 
    question = relationship('Post', remote_side=[id], backref=backref('answers'), uselist=False) 

測試:

session.add(
    Post(
     id=1, 
     post_id=None 
    ) 
) 
session.add(
    Post(
     id=2, 
     post_id=1 
    ) 
) 

session.add(
    Post(
     id=3, 
     post_id=1 
    ) 
) 

session.commit() 

question = session.query(Post).get(1) 
print question.answers # output [post2, post3] 
answer = session.query(Post).get(2) 
print answer.question.id # output 1 

# Receive all answers 
print session.query(Post).filter(Post.post_id.isnot(None)).all() 
1

您可以使用下面的問答表。

class Answer(Base): 
     __tablename__="answers" 
     id = Column(Integer, primary_key=True) 
     mcq_id = Column(Integer,ForeignKey('questions.id')) 
     answer_text = Column(Text()) 
     is_correct = Column(Boolean, nullable=False, default=False) 

    class Question(Base): 
     __tablename__="questions" 
     id = Column(Integer, primary_key=True) 
     question_text = Column(Text()) 
     answer_explanation = Column(Text()) 
     answer_choices = relationship('Answer', 
            primaryjoin="and_(Question.id == Answer.mcq_id)", 
            cascade="all, delete-orphan", 
            foreign_keys=[Answer.mcq_id]) 
# If you have more than one answers then define this function in your model. 
    def has_more_than_one_correct_answer(self): 
     count = 0 
     for choice in self.answer_choices: 
      if choice.is_correct: 
       count = count + 1 
     if count > 1: 
      return True 
     else: 
      return False 

您可以看到兩個表之間的關係。如果您使用的是sqlalchemy,則可以使用joinedloadjoinedload_all訪問該關係。

相關問題