flask-security:最小化数据库命中

问题描述 投票:0回答:3

在我的应用程序中,我使用了 flask-security 添加身份验证和授权主题。 SQLAlchemy 也用作数据提供者(以 MySQL 作为后端)。该应用程序运行良好。

然后,我做了一些 MySQL 跟踪,日志显示在应用程序上请求的每个 URL 上,flask-security 库都会发送两个数据库查询:

  • select ... from user where user.id = 'the user identifier'
  • select ... from role, roles_users ...

我认为这是一个性能问题,我喜欢尽量减少这些查询。 我不知道我是否缺少配置功能。

python flask flask-login flask-security
3个回答
1
投票

如果不进行进一步优化(例如使用 Redis 缓存 SQL 响应或用户对象),我认为您无法避免第一个请求。在大多数情况下,您需要有关用户的数据,并且您不希望将这些数据存储在用户的会话 cookie 中。同样,您可以使用 Redis 之类的东西在服务器端存储这些信息,并通过会话 ID 进行索引。

但是您可能可以使用 JOIN 来避免第二个请求。通过同时执行第一个和第二个请求,将为您节省一些传输时间+数据库将能够选择合适的查询计划。


1
投票

一种选择可能是覆盖 Flask-Login 的

user_loader
。不过,请参阅 this 讨论,了解为什么通常需要在每个请求上加载用户信息。

这就是 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 等)。在这种情况下,您将有 ~0 latency

 用于读取。


0
投票
我无法找到配置功能。我在 Flask-Security 中遇到了这个问题,因为它调用所有静态文件的用户表。 我可以使用 user_loader 的覆盖来解决这个问题。 这是我放入

init.py 中的代码:

# Override user_loader @security.login_manager.user_loader def user_loader(user_id): if request.path.startswith('/static/'): return None return user_datastore.find_user(fs_uniquifier=user_id)
    
© www.soinside.com 2019 - 2024. All rights reserved.