Flask sqlalchemy中瞬态模型的查询属性

Flask sqlalchemy中瞬态模型的查询属性,flask,sqlalchemy,flask-sqlalchemy,flask-login,Flask,Sqlalchemy,Flask Sqlalchemy,Flask Login,我正在使用烧瓶炼金术和烧瓶登录。 My flask登录的用户加载程序当前看起来如下所示: @login\u manager.user\u loader def加载用户(用户id): 返回User.query.filter_by(id=User_id).options(仅加载('id')).first() 这意味着每次用户需要登录load\u user() 将运行数据库查询以返回用户对象。在我的例子中,我几乎从不需要其他用户字段,如email、name等,因此我指定sqlalchemy只加载i

我正在使用烧瓶炼金术和烧瓶登录。

My flask登录的用户加载程序当前看起来如下所示:

@login\u manager.user\u loader
def加载用户(用户id):
返回User.query.filter_by(id=User_id).options(仅加载('id')).first()
这意味着每次用户需要登录
load\u user()
将运行数据库查询以返回用户对象。在我的例子中,我几乎从不需要其他用户字段,如email、name等,因此我指定sqlalchemy只加载id字段。这将允许mysql Optimizer相当快地执行查询

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

  • 当用户登录并获得会话时,可以保证为他存在唯一的id
  • Flask login的Cookie是使用我的密钥签名的,因此随机用户无法通过更改其id来伪造其用户id以模拟其他用户
此外,由于某些特定的业务原因,每个登录用户必须每1秒发送一次心跳信号。这意味着每隔一秒钟,就会执行这个用户id获取查询,在我的数据库服务器上造成相当大的负载(我有大约1000个用户同时这样做)。这个要求是不可协商的,我不能通过其他方法来提高速度,比如使用内存服务器

我想这样做:

@login\u manager.user\u loader
def加载用户(用户id):
返回用户(id=用户\u id)
请注意,在这种情况下,将返回一个带有用户id的假对象

从其他文件中,我知道

从flask\u登录导入当前用户
上面的一行为我提供了当前登录用户的句柄

然而,当我想要获取用户的其他属性,更重要的是它的关系时,使用我提出的方法是行不通的

这意味着我不能简单地使用当前用户的电子邮件,或者:

current_user.friends#这是一种关系
我尝试了这个,它只返回
None
。(但是,我可以像平常一样获得用户的id)

是否有任何方法可以实例化一个模型并使sqlalchemy认为我在创建模型时指定的任何属性都是sqlalchemy查询的结果? 本质上,让sqlalchemy认为使用
load\u only()
方法只加载了一些属性


这样,如果我使用当前用户。电子邮件如果尚未加载,它将获取电子邮件。

在与Michael Bayer(sqlalchemy的创建者)讨论此问题后,他建议以下解决方案:

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

从sqlalchemy.orm.session导入使\u暂时\u到\u分离
@登录\u manager.user\u加载程序
def加载用户(用户id):
u=User(id=int(User_id))#不会执行任何数据库查询
使_瞬态_至_分离(u)#这是建议的解决方案
db.session.add(u)#将分离的对象添加到会话
返回u
稍后,可以执行以下操作:

从flask\u登录导入当前用户
并访问当前用户的其他属性,如:

print(current_user.email)#将执行数据库查询以获取电子邮件