flask-security:减少数据库访问次数
在我的应用程序中,我使用了 flask-security 来处理用户的登录和权限管理。同时,我还用到了 SQLAlchemy 来管理数据,后端是 MySQL。这个应用运行得很好。
然后,我对 MySQL 进行了监控,发现每次在应用中请求一个网址时,flask-security 库都会发送两个数据库查询:
select ... from user where user.id = '用户标识'
select ... from role, roles_users ...
我觉得这可能会影响性能,所以想要减少这些查询。我不太确定是不是有什么配置我没有注意到。
2 个回答
0
一个选择是重写 Flask-Login 的 user_loader
。不过,看看 这个讨论,了解为什么在每次请求时加载用户信息通常是必要的。
这是 Flask-Security 实现 user_loader
的方式。
def _user_loader(user_id):
return _security.datastore.find_user(id=user_id)
这最终会生成一个 SQL 查询。
为了后续参考,这里有关于如何启用 sqlalchemy
发出的 SQL 查询的跟踪(调试)的方法:
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
另一种解决方案,可能有点复杂,就是为用户和角色设置一个单独的 SQL-lite 数据库(用于 Flask-Login、Flask-Security 等)。在这种情况下,读取的延迟几乎为零。
1
在不考虑进一步优化的情况下(比如使用Redis来缓存SQL的响应或用户对象),我认为你无法避免第一次请求。在大多数情况下,你需要用户的数据,而你又不想把这些数据存储在用户的会话cookie里。你可以考虑使用像Redis这样的工具,把这些信息存储在服务器端,并通过会话ID来索引。
不过,你可以尝试使用JOIN来避免第二次请求。通过同时进行第一次和第二次请求,可以节省一些传输时间,而且数据库也能选择一个合适的查询计划。