2017-09-18 4 views
0

Je travaille actuellement sur un projet, et j'ai quatre tables dans ma base de données - Utilisateur, Sujet, Question, Réponse. Chaque utilisateur peut suivre de nombreux sujets et questions, un sujet a de nombreux adeptes, une question a de nombreux suiveurs et réponses. De plus, une question peut être liée à plus d'un sujet.Flask-sqlalchemy: J'ai 4 tables, comment les joindre pour trouver les données que je veux

Maintenant, je veux trouver toutes les réponses sous les rubriques que je suis et je veux toutes les réponses triées par horodatage. Comment puis-je comprendre cela avec flask-sqlalchemy? J'ai travaillé toute la journée dessus mais je ne trouve pas la solution.

Voici le code:

class Question(db.Model): 
    __tablename__ = 'questions' 

    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(128), unique=True) 
    body = db.Column(db.Text()) 
    user_id = db.Column(db.Integer, db.ForeignKey('users.id')) 
    timestamp = db.Column(db.DateTime(), default=datetime.utcnow) 
    followers = db.relationship('User', 
           secondary=questions_users, 
           backref=db.backref('questions_following', lazy='dynamic'), 
           lazy='dynamic') 
    answers = db.relationship('Answer', backref='question', lazy='dynamic') 

class User(UserMixin, db.Model): 
    __tablename__ = 'users' 

    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String(64), unique=True) 
    email = db.Column(db.String(64), unique=True) 
    questions_asked = db.relationship('Question',backref='author', lazy='dynamic') 
    answers = db.relationship('Answer', backref='author', lazy='dynamic') 

questions_users = db.Table('questions_users', 
    db.Column('question_id', db.Integer, db.ForeignKey('questions.id')), 
    db.Column('follower_id', db.Integer, db.ForeignKey('users.id'))) 

class Topic(db.Model): 
    __tablename__ = 'topics' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(128), unique=True) 
    description = db.Column(db.Text()) 
    followers = db.relationship('User', 
          secondary=topics_users, 
          backref=db.backref('topics', lazy='dynamic'), 
          lazy='dynamic') 
    questions = db.relationship('Question', 
          secondary=topics_questions, 
          backref=db.backref('topics', lazy='dynamic'), 
          lazy='dynamic') 

class Answer(db.Model): 
    __tablename__ = 'answers' 

    id = db.Column(db.Integer, primary_key = True) 
    body = db.Column(db.Text()) 
    timestamp = db.Column(db.DateTime(), default=datetime.utcnow, index=True) 
    question_id = db.Column(db.Integer, db.ForeignKey('questions.id')) 
    user_id = db.Column(db.Integer, db.ForeignKey('users.id')) 



topics_users = db.Table('topics_users', 
    db.Column('topic_id', db.Integer, db.ForeignKey('topics.id')), 
    db.Column('user_id', db.Integer, db.ForeignKey('users.id'))) 


topics_questions = db.Table('topics_questions', 
    db.Column('topic_id', db.Integer, db.ForeignKey('topics.id')), 
    db.Column('question_id', db.Integer, db.ForeignKey('questions.id'))) 

Répondre

0

Si je vous ai bien compris, vous pouvez simplement join along Answer's question - topics - followers, filtre et commande:

In [7]: db.session.query(Answer).\ 
    ...:  join('question', 'topics', 'followers').\ 
    ...:  filter(User.id == 1).\ 
    ...:  order_by(Answer.timestamp) 

En raison du nombre de nombreuses relations une réponse peut être inclus plusieurs fois dans le jeu de résultats, mais comme SQLAlchemy déduit les requêtes d'entité unique, il ne s'agit pas d'un problème visible. La requête peut également être écrite en utilisant EXISTS:

In [11]: db.session.query(Answer).\ 
    ...:  join(Question).\ 
    ...:  filter(Question.topics.any(
    ...:   Topic.followers.any(
    ...:    User.id == 1))).\ 
    ...:  order_by(Answer.timestamp) 
+0

J'ai effectué un test et la deuxième méthode est correcte. Merci beaucoup, surtout pour le lien vers 'Query API' –

+0

Quel était le problème de la première? –