我正在使用Python3.6中的Peewee运行Django项目,并试图跟踪连接池的问题所在。我一直在开发服务器上得到以下错误(出于某些原因,我从来没有在本地机器上遇到过这个问题):
查询期间失去与MySQL服务器的连接
复制步骤是可靠的,它们是:
代码的结构使得所有的DB操作都在一个独立的Python模块中,这个模块导入到Django模块中。
在主类构造函数中,我将DB设置为:
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的调用都是这样完成的:
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,假设如果它小于等待超时,它可能会修复问题,但这并没有什么区别。
发布于 2018-11-29 15:59:04
在尝试了无数的想法之后,我终于想出了一个适用于我的案例的解决方案。不太理想,但很管用。这篇关于连接池的文章给我指明了正确的方向。
我创建了Django中间件类,并将其配置为Django中间件列表中的第一个。
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)发布于 2018-11-20 22:37:26
您需要确保正确地回收连接--这意味着当请求开始时,您打开连接,当响应被传递时,您关闭连接。池并不是最有可能回收康涅狄格的,因为你永远不会把它放回水池里,所以它看起来仍然“在使用”。使用中间件可以很容易地做到这一点,并在这里描述:
http://docs.peewee-orm.com/en/latest/peewee/database.html#django
https://stackoverflow.com/questions/53395272
复制相似问题