python - 在 SQLAlchemy 中注释 `exists` 子查询

标签 python flask sqlalchemy flask-sqlalchemy marshmallow

我有一个简单的新闻应用程序,用户可以在其中查看最新帖子,并且可以喜欢其中一些帖子。

型号:

from sqlalchemy.orm import relationship, backref

from app import db


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

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

class Like(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.ForeignKey(User.id))
    post_id = db.Column(db.ForeignKey(Post.id))
    post = relationship(Post, backref=backref('likes'))

我想要实现的目标是为每个帖子添加一个附加字段,该字段指示登录用户是否喜欢该帖子,但以优化的方式进行,而不需要对每个帖子进行查询。

我尝试在架构级别执行此操作,使用 marshmallow-sqlalchemy:

from marshmallow import fields

from app import ma
from news.models import Post

class PostSchema(ma.ModelSchema):
    is_liked = fields.Method("get_is_liked")

    def get_is_liked(self, obj):
        user = self.context['user']
        return bool(Like.filter_by(user_id=user.id, post_id=obj.id).first())

    class Meta:
        model = Post

但这会导致每个帖子都有 N 个查询。

我也尝试像 Django ORM 中的注释一样实现这一点:

class PostListView(Resource):

    # I have the user object here using a decorator
    def get(self, user):
        # I know that this is a bad syntax
        query = Post.query(Post.likes.filter_by(user_id=user.id).exists().label('is_liked')))

        schema = PostSchema(strict=True, many=True, context={"user": user})
        result = schema.dump(query.all())

        return result.data

我也看过这个answer其功能与我在数据库级别所需的功能相同,但我想使用 SQLAlchemy 来实现。

提前致谢。

最佳答案

这行得通吗?这个想法是加载帖子,以便 Post.likes 仅包含当前用户喜欢该帖子的情况。 contains_eager('likes') 应该在 Post 中加载 likes 数组。

# user_id is the id of the current user
q = session.query(Post) \
           .outerjoin(Like, and_(Like.post_id == Post.id,
                                 Like.user_id == user_id)) \
           .options(contains_eager('likes'))

那么 is_liked 可能类似于 return len(self.likes) > 0

关于python - 在 SQLAlchemy 中注释 `exists` 子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54669597/

相关文章:

python - Flask 和 Webapp2 (GAE) 的区别

python - Pandas 的问题

python - 在python中显示二进制文件中的数据

Python - 为什么我不能在 print 函数中使用生成器?

python - 如何正确运行查询 Flask-SQLAlchemy 数据库的连续测试?

postgresql - SQLAlchemy 在 Unix 套接字或 IPv4 之前尝试通过 IPv6 连接 PostgreSQL

python - 为什么改变环境和操作系统会改变 python flask 中的数据传输,为什么我应用的修复有效?

python - 调用 flask restful API 资源方法

python - 为什么人们使用sqlalchemy CORE保存数据并使用sqlalchemy ORM查询数据

sqlite - sqlalchemy sqlite "too many SQL variables"