In Worten, ich versuche, dieses Ziel zu erreichen:SQLAlchemy alle Zeilen zu zählen, möchte ich bestimmte Zeilen
„Get 5 Kommentare wo comment.post_id == self.context.id und die von der höchsten Zahl sortieren von Comment_Vote.vote_type == 'wie' "
Derzeit werden die Modelle sind:
vote_enum = ENUM('like', 'dislike', name='vote_enum', create_type=False)
class User(Base):
__tablename__='users'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(65), nullable=False)
comments = relationship('Comment', backref='user')
comment_vote = relationship('Comment_Vote', backref='user')
posts=relationship('Post', backref='user')
class Post(Base):
__tablename__ = 'post'
id = Column(Integer, primary_key=True, autoincrement=True)
body= Column(String(1500))
comments= relationship('Comment',backref='post', order_by='desc(Comment.date_created)', lazy='dynamic')
owner_id= Column(Integer, ForeignKey('users.id'))
class Comment(Base):
__tablename__='comment'
id = Column(Integer, primary_key=True, autoincrement=True)
body= Column(String(500))
parent_id = Column(Integer, ForeignKey('comment.id'))
post_id= Column(Integer, ForeignKey('post.id'))
user_id= Column(Integer, ForeignKey('users.id'))
children = relationship("Comment",
backref=backref('parent', remote_side=[id]),
lazy='dynamic'
)
del_flag= Column(Boolean, default=False)
date_created= Column(DateTime(), default=datetime.datetime.utcnow())
last_edited= Column(DateTime(), default=datetime.datetime.utcnow())
comment_vote= relationship("Comment_Vote", backref="comment", lazy='dynamic')
class Comment_Vote(Base):
__tablename__='comment_vote'
id = Column(Integer, primary_key=True, autoincrement=True)
user_id= Column(Integer, ForeignKey('users.id'))
comment_id= Column(Integer, ForeignKey('comment.id'))
vote_type = Column('vote_enum', vote_enum)
@classmethod
def total_likes(cls, comment_id, session):
return session.query(cls).filter(cls.id == comment_id).first().comment_vote.filter(Comment_Vote.vote_type=='like').count()
Meine Funktion Abfrage ist:
f = session.query(Comment_Vote.comment_id, funcfilter(func.count(1), Comment_Vote.vote_type == 'like').label('total_likes')).group_by(Comment_Vote.comment_id).subquery()
comments = session.query(Comment, f.c.total_likes).join(f, Comment.id==f.c.comment_id).filter(Comment.post_id == self.context.id).order_by('total_likes DESC').limit(5)
Das hat den unangenehmen Nebeneffekt, ALLE "likes" von comment_vote zu zählen, sogar für Kommentare, die für diesen Beitrag nicht relevant sind.
Ich wäre wirklich dankbar für ein paar Tipps, wie man das neu anordnet, so dass es nicht alles zuerst zählen musste. Was ich will, ist vielleicht nicht möglich, und ich arbeite meistens innerhalb des ORM.
DB hinter dem SQLAlchemy ist Postgresql.
Was ist 'funcfilter'? – univerio
http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.funcfilter Eine andere Art zu sagen, filter(), so ziemlich. Es wurde gemacht, weil der Filter nicht richtig gezählt wurde. – Vyndion
Heh, ich dachte es wäre etwas was du definiert hast. Sie können versuchen, einen Join direkt zu machen, anstatt einen Join zu einer Unterabfrage zu machen: 'SELECT comment.id, count (*) AS total_likes FROM Kommentar JOIN comment_vote ON comment.id = comment_id WHERE Kommentar.post_id =: id AND vote_type = 'like 'GROUP BY Kommentar.ID'. – univerio