【问题标题】:Sql Alchemy QueuePool limit overflowSql Alchemy QueuePool 限制溢出
【发布时间】:2014-09-17 09:02:47
【问题描述】:

我有一个返回 TimeOut 的 Sql Alchemy 应用程序:

TimeoutError: QueuePool limit of size 5 overflow 10达到, 连接超时,超时 30

我在另一篇文章中读到,当我不关闭会话时会发生这种情况,但我不知道这是否适用于我的代码:

我在init.py中连接数据库:

from .dbmodels import (
    DBSession,
    Base,    

engine = create_engine("mysql://" + loadConfigVar("user") + ":" + loadConfigVar("password") + "@" + loadConfigVar("host") + "/" + loadConfigVar("schema"))

#Sets the engine to the session and the Base model class
DBSession.configure(bind=engine)
Base.metadata.bind = engine

然后在另一个 python 文件中,我在两个函数中收集了一些数据,但使用了我在 init.py 中初始化的 DBSession:

from .dbmodels import DBSession
from .dbmodels import resourcestatsModel

def getFeaturedGroups(max = 1):

    try:
        #Get the number of download per resource
        transaction.commit()
        rescount = DBSession.connection().execute("select resource_id,count(resource_id) as total FROM resourcestats")

        #Move the data to an array
        resources = []
        data = {}
        for row in rescount:
            data["resource_id"] = row.resource_id
            data["total"] = row.total
            resources.append(data)

        #Get the list of groups
        group_list = toolkit.get_action('group_list')({}, {})
        for group in group_list:
            #Get the details of each group
            group_info = toolkit.get_action('group_show')({}, {'id': group})
            #Count the features of the group
            addFesturedCount(resources,group,group_info)

        #Order the FeaturedGroups by total
        FeaturedGroups.sort(key=lambda x: x["total"],reverse=True)

        print FeaturedGroups
        #Move the data of the group to the result array.
        result = []
        count = 0
        for group in FeaturedGroups:
            group_info = toolkit.get_action('group_show')({}, {'id': group["group_id"]})
            result.append(group_info)
            count = count +1
            if count == max:
                break

        return result
    except:
        return []


    def getResourceStats(resourceID):
        transaction.commit()
        return  DBSession.query(resourcestatsModel).filter_by(resource_id = resourceID).count()

会话变量是这样创建的:

#Basic SQLAlchemy types
from sqlalchemy import (
    Column,
    Text,
    DateTime,
    Integer,
    ForeignKey
    )
# Use SQLAlchemy declarative type
from sqlalchemy.ext.declarative import declarative_base

#
from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    )

#Use Zope' sqlalchemy  transaction manager
from zope.sqlalchemy import ZopeTransactionExtension

#Main plugin session
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))

因为会话是在 init.py 和后续代码中创建的,所以我只是使用它;在什么时候我需要关闭会话?或者我还需要做什么来管理池大小?

【问题讨论】:

  • 第二个代码sn-p中,transaction定义在哪里?
  • getResourceStats 在哪里使用?看起来有一半的代码丢失了 - 你能把它全部添加进去吗,否则可能无法诊断问题。
  • 此代码是否按原样工作?除了@TomDalton 提到的问题之外,import 语句看起来真的很奇怪。错误发生在什么时候?这是Minimal, Complete, Verifiable example吗? IOW,您能否完全(或显着)减少这种情况并仍然表现出相同的行为?那里似乎有很多业务逻辑,不太可能是问题的原因。尝试删除它,并发布一个完整的工作(语法正确)示例,我很乐意提供帮助。

标签: python session sqlalchemy zope connection-timeout


【解决方案1】:

您可以通过在函数create_engine中添加参数pool_size和max_overflow来管理池大小

engine = create_engine("mysql://" + loadConfigVar("user") + ":" + loadConfigVar("password") + "@" + loadConfigVar("host") + "/" + loadConfigVar("schema"), 
                        pool_size=20, max_overflow=0)

参考是here

您无需关闭会话,但应在您的事务完成后关闭连接。 替换:

rescount = DBSession.connection().execute("select resource_id,count(resource_id) as total FROM resourcestats")

作者:

connection = DBSession.connection()
try:
    rescount = connection.execute("select resource_id,count(resource_id) as total FROM resourcestats")
    #do something
finally:
    connection.close()

参考是here

另外,请注意,mysql 已经过时的连接会在特定时间后关闭(这个时间可以在 MySQL 中配置,我不记得默认值),因此您需要将 pool_recycle 值传递给引擎创建

【讨论】:

【解决方案2】:

将以下方法添加到您的代码中。它将自动关闭所有未使用/挂起的连接并防止代码出现瓶颈。特别是如果您使用以下语法 Model.query.filter_by(attribute=var).first() 和关系/延迟加载。

   @app.teardown_appcontext
    def shutdown_session(exception=None):
        db.session.remove()

相关文档可在此处获得:http://flask.pocoo.org/docs/1.0/appcontext/

【讨论】:

  • 不请求上下文?
猜你喜欢
  • 2018-04-14
  • 2016-11-12
  • 2021-08-22
  • 2016-09-29
  • 2020-02-20
  • 2016-11-25
  • 2018-12-07
  • 2021-12-31
  • 2016-12-13
相关资源
最近更新 更多