O SQLAlchemy ordenação por contagem em um relacionamento muitos-para-muitos
-
12-11-2019 - |
Pergunta
Este é um exemplo simplificado de meus modelos da corrente (Eu estou usando o Frasco SQLAlchemy extensão):
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'
)
Estou tentando encomendar Post
's pela quantidade de gosta de ele tem.
Esta é a consulta que eu estou basicamente tentando problema:
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
Eu só não tenho sido capaz de obter qualquer coisa que trabalhar no SQLAlchemy lado das coisas.
Obrigado por qualquer ajuda que alguém pode oferecer.
Solução
Eu não usei o SQLAlchemy muito, então eu percebi que eu daria um tiro.Eu não tentar usar seus modelos, eu escrevi alguns novos (semelhante o suficiente):
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
Você quer juntar-se a likes
tabela, use func.count
para contar gosta, group_by
Post
e, em seguida, usar order_by
:
db.session.query(Post, func.count(likes.c.user_id).label('total')).join(likes).group_by(Post).order_by('total DESC')
Eu encontrei o ORM tutorial e o resto do SQLAlchemy documentação muito útil.