【问题标题】:How to create a self-referencing one-to-many relationship in Flask-SQLAlchemy?如何在 Flask-SQLAlchemy 中创建自引用的一对多关系?
【发布时间】:2016-09-27 10:00:42
【问题描述】:

我有一个名为 Post 的模型,它有一个名为 is_answer 的布尔字段。如果Postis_answer 字段为True,则为“问题”;否则,这是一个“答案”。我想创建以下问答关系:

一个“问题”可能有多个“答案”,但一个“答案”有且只有一个“问题”。由于“问题”和“答案”本质上都是Posts,我认为关系一定是自引用的。

这是我尝试过的:

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 和反向引用 Post.answer 都是 相同方向的符号('ONETOMANY')。你的意思是设置 remote_side 在多对一方面?

【问题讨论】:

    标签: database sqlalchemy one-to-many flask-sqlalchemy self-referencing-table


    【解决方案1】:

    您需要添加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()
    

    【讨论】:

      【解决方案2】:

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

      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 访问关系。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 2016-06-15
        • 2021-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多