我有一个名为Post
的模型,它有一个名为is_answer
的布尔字段。如果Post
的is_answer
字段为True,则为"问题";否则,它就是一个"答案"。我想创建以下问答关系:
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:职位。问题和参考资料。答案都是同一方向符号('ONETOMANY')。你是故意的吗Remote_side在多对一的一侧?
需要添加remote_side
参数来创建自引用关系。更多信息见文档。
UPDATED:顺便说一下,我认为你不需要布尔标志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()
你可以使用下面的问答表。
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,则可以使用joinedload
或joinedload_all
访问关系。