Python sqlalchemy:如何使用该关系从多个到多个计数数据

时间:2018-04-12 10:24:08

标签: python sqlalchemy

我有User

我有Post

用户可以投票,这里我使用了UserVotesPost表,这是一个多对多关系。

以下是代码:

class UserVotesPost(Base):
    __tablename__ = 'uservotesposts'
    user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
    post_id = Column(Integer, ForeignKey('posts.id'), primary_key=True)
    likes_post = Column(Boolean, nullable=False)
    date_added = Column(DateTime, nullable=False)
    child = relationship("Post")

class User(UserMixin, Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    email = Column(Text, nullable=False, unique=True)
    password = Column(Text, nullable=False)
    children_UserVotesPost = relationship("UserVotesPost")
    # etc ...

class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True)
    title = Column(Text, nullable=False)
    description = Column(Text, nullable=True)
    created_on = Column(DateTime, nullable=False)
    updated_on = Column(DateTime, nullable=False)
    views = Column(Integer, nullable=False, default=0)
    visible_to_tier_id = Column(Integer, nullable=True)
    hidden_post = Column(Boolean, nullable=False, default=False)
    # etc ...

添加数据工作正常,但现在我想通过使用关系& amp;来显示数据。正确的语法。

我想要的是显示视野中某个帖子的喜欢和不喜欢的总量。

到目前为止我的想法:

我可以简单地查询所有UserVotesPost并创建嵌套的for ... if循环以便比较和计算帖子。那看起来像那样:

all_votes = UserVotesPost.query.all()
all_posts = Post.query.all()

在视图中:

{% for post in all_posts  %}
    {% for vote in all votes %}
         {% if post.id == vote.post_id %}
             {% if vote.likes_post == True %}
                 # increase count for likes true 
             {% else %}   
                 # increase count for likes false
             {% endif %}
         {% endif %}
     {% endfor %} 
{% endfor %}

但这是一个完整的解决方法,它不使用数据库关系,可能对性能非常不利。但它会起作用。

我目前正在玩这种关系,但到目前为止,我只是通过使用关系设法让所有用户喜欢/不喜欢:

for vote in current_user.children_UserVotesPost:
    print (vote.likes_post)

1 个答案:

答案 0 :(得分:0)

感谢@IljaEverilä向我展示了正确的主题。我遵循了这个帖子中提出的解决方案:SO Thread

您可以在模型类中使用@property来定义需要在某处显示的某些数据。

除此之外,我还要将PostUserVotesPost关联起来:

class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True)
    title = Column(Text, nullable=False)
    description = Column(Text, nullable=True)
    created_on = Column(DateTime, nullable=False)
    updated_on = Column(DateTime, nullable=False)
    views = Column(Integer, nullable=False, default=0)
    visible_to_tier_id = Column(Integer, nullable=True)
    hidden_post = Column(Boolean, nullable=False, default=False)
    # This has been added:
    children_UserVotesPost = relationship("UserVotesPost")

我在Post类中创建了两个属性:

@property
def count_votes_up(self):
    return object_session(self).query(UserVotesPost).filter(UserVotesPost.likes_post == True).with_parent(self).count()

@property
def count_votes_down(self):
    return object_session(self).query(UserVotesPost).filter(UserVotesPost.likes_post == False).with_parent(self).count()

您还需要导入object_session

from sqlalchemy.orm import object_session

现在很容易在python或view中访问数据:

all_posts = Post.query.all()
for p in all_posts:
    print (p.id, ' has ', p.count_votes_up, ' ups')
    print (p.id, ' has ', p.count_votes_down, ' downs')