[ SQLAlchemy ] 关于dynamic的“一知半解”

问题提出:

1.粉丝机制

2.评论的点赞功能

这两个功能分别由User类和Comment类来实现,同样定义了多对多的关系,查询的时候用的方法却大不一样,先看看代码吧。

###
#  User类的中间表
followers = db.Table(
    'followers',
    db.Column('follower_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('followed_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('timestamp', db.DateTime, default=datetime.utcnow)
)

# Comment类的中间表
comments_likes = db.Table(
    'comments_likes',
    db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('comment_id', db.Integer, db.ForeignKey('comments.id')),
    db.Column('timestamp', db.DateTime, default=datetime.utcnow)
)
###


class User(PaginatedAPIMixin, db.Model):
    ...
    # followeds 是该用户关注了哪些用户列表
    # followers 是该用户的粉丝列表
    followeds = db.relationship(
        'User', secondary=followers,
        primaryjoin=(followers.c.follower_id == id),
        secondaryjoin=(followers.c.followed_id == id),
        backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
    def is_following(self,user):
        '''
        判断有没有关注 user 这个用户
        '''
        return self.followeds.filter(followers.c.followed_id == user.id).count()>0


class Comment(PaginatedAPIMixin, db.Model):
    __tablename__ = 'comments'
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.Text)
    ...
    likers = db.relationship(
        'User',
        secondary=comments_likes,
        backref=db.backref('liked_comments',lazy='dynamic')
    )
    def is_liked_by(self, user):
        '''
        判断用户 user 是否已经对该评论点过赞
        '''
        return user in self.likers

 从上面的代码看出,同样是多对多的关系

为何User类中高亮部分的followeds是可查询的对象

而Comment类中高亮部分的likers是列表呢?

原因分析

1.先看User类中定义的followeds,正向查询(使用user.followeds)的时候会用到 lazy='dynamic' ,反向查询(使用user.followers)的时候同样也会用到。

2.再看Comment类中定义的likers,只有反向查询的时候才会用到 lazy='dynamic' 

所以说,关键在于是否用到 lazy='dynamic' 。

查看flask-SQLAlchemy文档http://www.pythondoc.com/flask-sqlalchemy/models.html#one-to-many :

'dynamic' 在有多条数据的时候是特别有用的。不是直接加载这些数据,SQLAlchemy 会返回一个查询对象,在加载数据前您可以过滤(提取)它们。
原文地址:https://www.cnblogs.com/remly/p/12168752.html