【发布时间】: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