首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带Peewee连接池的Django MySQL断开连接

问带Peewee连接池的Django MySQL断开连接
EN

Stack Overflow用户
提问于 2018-11-20 14:32:10
回答 2查看 1.1K关注 0票数 1

我正在使用Python3.6中的Peewee运行Django项目,并试图跟踪连接池的问题所在。我一直在开发服务器上得到以下错误(出于某些原因,我从来没有在本地机器上遇到过这个问题):

查询期间失去与MySQL服务器的连接

复制步骤是可靠的,它们是:

  1. 在实例上重新启动Apache。
  2. 转到我的Django页面,按一个触发DB操作的按钮。
  3. 效果很好。
  4. 等待10分钟(我已经做了足够的测试,得到了确切的数字)。
  5. 按另一个按钮以触发另一个DB操作。
  6. 获取上面丢失的连接错误。

代码的结构使得所有的DB操作都在一个独立的Python模块中,这个模块导入到Django模块中。

在主类构造函数中,我将DB设置为:

代码语言:javascript
复制
from playhouse.pool import PooledMySQLDatabase

def __init__(self, host, database, user, password, stale_timeout=300):
    self.mysql_db = PooledMySQLDatabase(host=host, database=database, user=user, password=password, stale_timeout=stale_timeout)
    db_proxy.initialize(self.mysql_db)

每个需要调用DB的调用都是这样完成的:

代码语言:javascript
复制
def get_user_by_id(self, user_id):
    db_proxy.connect(reuse_if_open=True)
    user = (User.get(User.user_id == user_id))
    db_proxy.close()
    return {'id': user.user_id, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email }

我查看了MySQL实例上的MySQL值,其值为3600,因此这似乎不是问题所在(而且我尝试更改它只是为了查看)。

对我在这里可能做错了什么有什么想法吗?

更新:

我发现MySQL的MySQL配置文件将wait-timeout值设置为600,这与我正在经历的情况相匹配。我不知道当我在SHOW VARIABLES LIKE 'wait_timeout'; DB上运行MySQL (返回3600)时,为什么这个值没有显示出来,但问题似乎来自等待超时。

考虑到这一点,我尝试将陈旧的超时设置为60,假设如果它小于等待超时,它可能会修复问题,但这并没有什么区别。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-29 15:59:04

在尝试了无数的想法之后,我终于想出了一个适用于我的案例的解决方案。不太理想,但很管用。这篇关于连接池的文章给我指明了正确的方向。

我创建了Django中间件类,并将其配置为Django中间件列表中的第一个。

代码语言:javascript
复制
from peewee import OperationalError
from playhouse.pool import PooledMySQLDatabase

database = PooledMySQLDatabase(None)

class PeeweeConnectionMiddleware(object):

    CONN_FAILURE_CODES = [ 2006, 2013, ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if database.database: # Is DB initialized?
            response = None
            try:
                database.connect(reuse_if_open=True)
                with database.atomic() as transaction:
                    try:
                        response = self.get_response(request)
                    except:
                        transaction.rollback()
                        raise
            except OperationalError as exception:
                if exception.args[0] in self.CONN_FAILURE_CODES:
                    database.close_all()
                    database.connect()
                    response = None
                    with database.atomic() as transaction:
                        try:
                            response = self.get_response(request)
                        except:
                            transaction.rollback()
                            raise
                else:
                    raise
            finally:
                if not database.is_closed():
                    database.close()
            return response
        else:
            return self.get_response(request)
票数 0
EN

Stack Overflow用户

发布于 2018-11-20 22:37:26

您需要确保正确地回收连接--这意味着当请求开始时,您打开连接,当响应被传递时,您关闭连接。池并不是最有可能回收康涅狄格的,因为你永远不会把它放回水池里,所以它看起来仍然“在使用”。使用中间件可以很容易地做到这一点,并在这里描述:

http://docs.peewee-orm.com/en/latest/peewee/database.html#django

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53395272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档