Python 使用flask sqlalchmey模型类进行的查询导致数据库会话泄漏

Python 使用flask sqlalchmey模型类进行的查询导致数据库会话泄漏,python,session,flask,flask-sqlalchemy,Python,Session,Flask,Flask Sqlalchemy,我现在很沮丧。当使用类类型(即User.query.filter(…)或类本身的实例(即u=User(…);返回u.query.filter(…).first())执行DB查询时,我会遇到这个问题 最终,当我尝试执行添加/提交时,我得到了谚语: InvalidRequestError: Object '<Loadable at 0x1b02f90>' is already attached to session '1' (this is '4') 所有页面请求都会调用load\u

我现在很沮丧。当使用类类型(即
User.query.filter(…)
或类本身的实例(即
u=User(…)
返回u.query.filter(…).first()
)执行DB查询时,我会遇到这个问题

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

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

所有页面请求都会调用
load\u user()
,每次命中它时,我都会有一个新会话。我可以自信地说,因为我在
/lib/python2.7/site packages/sqlalchemy/orm/session.py

对于会话的创建和破坏。我希望它是一个小东西,可以指出我对这些东西是如何分配的严重误解。我一开始满头头发,但我已经为这一点挠头太久了,现在我要秃头了。请保存我的头发

因此,采纳Miguel的建议,在
lib/python2.7/site packages/flask\u sqlalchemy/\uuuuu init\uuuuu.py(137)\uuuuuu init\uuuu()

我能够看到这是我编写的一个函数的结果,该函数逐个加载它在给定目录中看到的所有模块。堆栈跟踪如下:

  /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()
/home/robert/snak2/run.py(1)()
->从应用程序导入应用程序
/home/robert/snak2/app/_uuuinit.py(39)()
->从\u目录(“应用程序”)加载\u所有\u模块\u
/home/robert/snak2/app/utils.py(87)从目录()加载所有模块
->)。加载\u模块(完整\u包\u名称)
/usr/lib64/python2.7/pkgutil.py(246)加载模块()
->mod=imp.load_模块(全名、self.file、self.filename、self.etc)
/home/robert/snak2/app/account/__init.py(17)()
->mod.mod_寄存器(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\u sqlalchemy/\uuuuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
->返回类型.query\u类(映射器,session=self.sa.session())
/home/robert/snak2/env/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py(70)\u调用
->返回self.registry()
/home/robert/snak2/env/lib/python2.7/site-packages/sqlalchemy/util/_-collections.py(864)uuu-calls_uu()
->返回self.registry.setdefault(项,self.createfunc())
>/home/robert/snak2/env/lib/python2.7/site packages/flask\u sqlalchemy/\uuuuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
->self.app=db.get_app()

根据Miguel在kick a$$教程中提供的信息,我认为堆栈中用(**)表示的行实际上导致创建(并持续)新会话。但是如何让它消失呢?

每个请求都会获得一个新的数据库会话,这是正常的,也是意料之中的。您遇到的问题不是您正在泄漏会话,而是有史以来创建的第一个会话(编号为1的会话)附加了对象,并且没有发布。你是在用烧瓶炼金术吗?扩展中有一个错误导致了这个错误。嘿,米格尔,谢谢你回复我。如果你是发布flask mega教程的同一个人,首先让我说你是摇滚明星。这些信息相当丰富。话虽如此,我想我知道你在这里得到了什么——我看到了找到那只虫子的过程。不幸的是,我没有使用烧瓶法。我之所以在这里使用“泄漏”一词,是因为我不知道如何返回并重新访问这些会话。如果是的话,我会自己关上的-/是的,我就是那个家伙。我相信这不是“会议”,只是因为某种原因而被卡住的一次会议。您可以使用调试器获取更多信息。在会话构造函数中放置断点,然后启动应用程序。当它中断时,您将有一个堆栈跟踪,它将告诉您是谁创建了永远不会消失的会话1。希望这能给你更多的线索。太棒了!谢谢你宝贵的时间!根据您的建议并在会话构造位置设置断点,我可以看到它来自于我编写的一个函数,该函数注册了它在给定目录中看到的所有模块。我将更新帖子。您没有提供足够的代码作为最小可见程序。所以无法诊断。通常情况下,
db
用于创建模型,而
db.init\u app()
则不一样。希望这条线索能有所帮助。
  /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()