【问题标题】:Querying properties of transient models in sqlalchemy在 sqlalchemy 中查询瞬态模型的属性
【发布时间】:2018-08-10 06:41:00
【问题描述】:

我正在使用 flask-sqlalchemy 和 flask-login。

我的烧瓶登录的用户加载器当前如下所示:

@login_manager.user_loader
def load_user(user_id):
    return User.query.filter_by(id=user_id).options(load_only('id')).first()

这意味着每次用户需要登录load_user() 将运行数据库查询以返回用户对象。在我的情况下,我几乎从不需要其他用户字段,如电子邮件、姓名等,所以我指定 sqlalchemy 只加载 id 字段。这将允许 mysql 优化器相当快地执行查询。

但是,我什至不需要执行此查询,因为:

  • 当用户登录并获得会话时,可以保证他存在唯一的 ID。
  • Flask-login 的 cookie 是使用我的密钥签名的,因此随机用户无法通过更改他的 id 来欺骗他的用户 id 来冒充其他用户。

另外,由于某些特定的业务原因,每个登录的用户都必须每 1 秒发送一次心跳信号。这意味着每秒都会执行此用户 ID 获取查询,从而在我的数据库服务器上产生相当大的负载(我有大约 1000 个用户同时执行此操作)。这个要求是不可协商的,我无法通过其他方法来提高速度,比如使用内存服务器。

我想这样做:

@login_manager.user_loader
def load_user(user_id):
    return User(id=user_id)

请注意,在这种情况下,会返回一个带有用户 ID 的假对象。

从其他文件,我做

from flask_login import current_user

上面的行给了我当前登录用户的句柄。

但是,当我想获取用户的其他属性,更重要的是它的关系时,使用我提出的方法将不起作用。

这意味着我不能简单地做current_user.email,或者:

current_user.friends #this is a relationship

我试过了,它只是返回None。 (但是,我可以像往常一样获取用户的 id)

有没有办法实例化一个模型并使 sqlalchemy 认为我在创建模型时指定的任何属性都是 sqlalchemy 查询的结果? 本质上让 sqlalchemy 认为只有一些属性是使用 load_only() 方法加载的。

这样,如果我执行current_user.email,它将获取尚未加载的电子邮件。

【问题讨论】:

    标签: flask sqlalchemy flask-sqlalchemy flask-login


    【解决方案1】:

    在与 Michael Bayer(sqlalchemy 的创建者)here 讨论了这个问题后,这是他建议的解决方案:

    使对象表现得像分离和过期,然后与会话关联:

    from sqlalchemy.orm.session import make_transient_to_detached 
    
    @login_manager.user_loader
    def load_user(user_id):
        u = User(id=int(user_id))     # will not do any db query
        make_transient_to_detached(u) # This is the suggested solution
        db.session.add(u)             # add the detached object to session
        return u
    

    稍后,它可能会这样做:

    from flask_login import current_user
    

    并访问 current_user 的其他属性,例如:

    print(current_user.email)  # will perform a database query to fetch email
    

    【讨论】:

      猜你喜欢
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2012-02-25
      • 2011-07-20
      相关资源
      最近更新 更多