0

J'ai un modèle nommé Post, qui a un champ booléen appelé is_answer. Si le champ is_answer d'un Post est True, il s'agit d'une "question"; sinon, c'est une "réponse". Je veux créer la relation question-réponse suivante:Comment créer une relation un-à-plusieurs auto-référencée dans Flask-SQLAlchemy?

Une "question" peut avoir plusieurs "réponses", mais une "réponse" a et n'a qu'une "question". En raison du fait que les deux "question" et "réponse" sont essentiellement Post s, je pense que la relation doit être auto-référence.

Voici ce que j'ai essayé:

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

L'erreur est:

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 ?

Répondre

2

Vous devez ajouter l'argument remote_side pour créer relation auto-référencé. Plus d'informations dans documentaion.

MIS A JOUR: D'ailleurs, je pense que vous n'avez pas besoin booléenne drapeau is_question, parce que vous pouvez déterminer les questions et les réponses en vérifiant post_id champ est Null ou non.

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) 

Test:

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

Vous pouvez utiliser la question ci-dessous et une table répondre.

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 

Vous pouvez voir la relation entre deux tables. Et vous pouvez accéder à la relation en utilisant joinedload ou joinedload_all si vous utilisez sqlalchemy.