2011-05-12 5 views
21

Ceci est un exemple simplifié de mes modèles actuels (j'utilise le Flask SQLAlchemy extension):commande SQLAlchemy par comptage sur plusieurs à plusieurs

like = db.Table(
    'like', 
    db.Column('uid', db.Integer, db.ForeignKey('users.id')), 
    db.Column('pid', db.Integer, db.ForeignKey('posts.id')) 
) 

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

    id = db.Column(db.Integer, primary_key = True) 
    username = db.Column(db.String(20)) 

class Post(db.Model): 
    __tablename__ = 'posts' 

    id = db.Column(db.Integer, primary_key = True) 
    title = db.Column(db.String(255)) 

    likes = db.relationship(
     'User', 
     secondary = like, 
     backref = db.backref('likes', lazy = 'dynamic'), 
     lazy = 'dynamic' 
    ) 

Je suis en train de commander Post « s par le montant de aime il a.

C'est la requête que je suis essentiellement essayer de problème:

SELECT p.*, COUNT(l.`pid`) as `likes` 
FROM `posts` as p 
LEFT JOIN `like` as l 
    ON p.`id` = l.`pid` 
GROUP BY p.`id` 
ORDER BY `likes` DESC 

Je viens pas été en mesure d'obtenir quoi que ce soit sur le côté travail SQLAlchemy des choses.

Merci pour toute aide que vous pouvez offrir.

Répondre

35

Je n'ai pas beaucoup utilisé SQLAlchemy, donc je me suis dit que j'allais tenter le coup. Je n'ai pas essayé d'utiliser vos modèles, je viens d'écrire quelques nouvelles (similaires assez bien):

likes = db.Table('likes', 
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')), 
    db.Column('post_id', db.Integer, db.ForeignKey('post.id')) 
) 

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String(20)) 

    def __repr__(self): 
     return "<User('%s')>" % self.username 

class Post(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(255)) 

    likes = db.relationship('User', secondary = likes, 
     backref = db.backref('posts', lazy='dynamic')) 

    def __repr__(self): 
     return "<Post('%s')>" % self.title 

Vous souhaitez rejoindre la table likes, utilisez func.count compter goûts, group_byPost puis utilisez order_by:

db.session.query(Post, func.count(likes.c.user_id).label('total')).join(likes).group_by(Post).order_by('total DESC') 

Je trouve le ORM tutorial et le reste de la documentation SQLAlchemy très utile.

+0

Salut, merci pour la réponse. Peu de choses à noter cependant. Vous avez une parenthèse supplémentaire à la fin de la requête. MySQL n'a pas aimé le '' -total'' _ ('' total DESC' fonctionne bien) _. Aussi, je pense qu'il est peut-être préférable de simplement grouper sur l'id donc '.group_by (Post.id)'. Enfin, j'ai eu un problème avec 'func.count (likes)'. Il se traduisait par un compte vide _ ('COUNT()') _. Le fait de fournir une colonne l'a corrigé avec 'func.count (likes.c.did)'. Merci encore. – anomareh

+0

@anomareh Super, content que ça aide. Je mettrai à jour ma réponse pour qu'elle soit plus utile (espérons-le). Je me demande si différentes versions de SQLAlchemy importent ici? J'utilisais 0.7b4. – zeekay

+0

Pourrait être, j'utilisais 0.6.7. – anomareh

Questions connexes