• [ 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 会返回一个查询对象,在加载数据前您可以过滤(提取)它们。
  • 相关阅读:
    BroadcastReceiver 小结
    Android Manifest.xml 之 Intent-filter
    First Phone Interview
    XDK html development --- Cross Domain Request
    Github Git usage
    为节省内存,动态添加view布局和控件
    相似的概念
    让一个view 获得焦点
    ListView 关于减少耗时方法调用优化
    SearchView 分解设置属性
  • 原文地址:https://www.cnblogs.com/remly/p/12168752.html
Copyright © 2020-2023  润新知