使用flask-sqlalchemy模型类进行查询,导致数据库会话泄漏

时间:2013-11-24 02:55:40

标签: python session flask flask-sqlalchemy

现在非常沮丧。我有这个问题,使用类类型(即User.query.filter(...)或类本身的实例(即u = User(...); return u.query.filter(...).first())执行数据库查询会导致每次创建一个新会话

最后,当我尝试执行添加/提交时,我得到了谚语:

InvalidRequestError: Object '<Loadable at 0x1b02f90>' is already attached to session '1' (this is '4')

对于它的价值,我发现新的会话继续由以下原因创建:

app/_ _ init _ _.py:

@login_manager.user_loader

def load_user(id):

from app.users.models import User
return User.query.get(int(id))

所有页面请求都会调用load_user(),每次点击时,我都会有一个新会话。我可以自信地这样说,因为我在中设置了断点  /lib/python2.7/site-packages/sqlalchemy/orm/session.py
用于创建和销毁会话。我希望它有点小,可以指出我对如何分配这些东西的严重误解。我开始一整天的头发,但是我已经在这一个上刮了很长时间,因为我已经秃了。请保存我的头发。

因此,采取Miguel的建议并在会话创建地点设置断点 lib/python2.7/site-packages/flask_sqlalchemy/__init__.py(137)__init__()
我能够看到它是我编写的一个函数的结果,它逐个加载它在给定目录中看到的所有模块。下面的堆栈跟踪:

  /home/robert/snak2/run.py(1)<module>()
-> from app import app
  /home/robert/snak2/app/__init__.py(39)<module>()
-> load_all_modules_from_dir('app')
  /home/robert/snak2/app/utils.py(87)load_all_modules_from_dir()
-> ).load_module(full_package_name)
  /usr/lib64/python2.7/pkgutil.py(246)load_module()
-> mod = imp.load_module(fullname, self.file, self.filename, self.etc)
  /home/robert/snak2/app/account/__init__.py(17)<module>()
-> mod.mod_register(MODNAME, MODCAT, NAME, LINK, AUTHOR, DESC, ICON, NAVS)
  /home/robert/snak2/app/loader.py(159)mod_register()
**-> mod = Loadable.query.filter(Loadable.modname == modname).first()(**)**
  /home/robert/snak2/env/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py(429)__get__()
-> return type.query_class(mapper, session=self.sa.session())
  /home/robert/snak2/env/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py(70)__call__()
-> return self.registry()
  /home/robert/snak2/env/lib/python2.7/site-packages/sqlalchemy/util/_collections.py(864)__call__()
-> return self.registry.setdefault(key, self.createfunc())
> /home/robert/snak2/env/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py(137)__init__()
-> self.app = db.get_app()

基于Miguel在他的kick教程中给出的信息,我相信它是用(**)表示的堆栈中的行实际上导致创建一个新会话(并且持久化)。但是如何让它消失呢?

0 个答案:

没有答案