Django 自定义装饰器解决MySQL server has gone away错误

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Django 自定义装饰器解决MySQL server has gone away错误

Django 自定义装饰器解决MySQL server has gone away错误


 

测试环境

Win 10

 

Python 3.5.4

 

Django-2.0.13.tar.gz

官方下载地址:

https://www.djangoproject.com/download/2.0.13/tarball/

 

 

问题描述

实际项目开发中,编写定时任务,通过Django自带的orm去操作数据库,发现某次执行程序报错:

MySQL server has gone away

 

原因分析

mysql数据库存在超时关闭非活动状态连接的机制,导致Django获取的连接失效,但是Django自身并不知道。当我们在前端通过api、web页面发送request,Django处理request时会发送Signals,进而触发连接状态检查,自动关闭不可用连接,又因为不存在可用连接的情况下,Django会自动重新创建数据库连接,执行我们想要的操作,所以一般情况不会报这个错误。但是当我们使用定时任务,直接使用orm去操作数据库时并不会触发发送Signals的操作,拿着失效连接去操作数据库,然后就报错了

 

参考链接:

https://docs.djangoproject.com/en/1.8/ref/signals/#module-django.db.models.signals

 

解决方法

自定义关闭不可用连接装饰器,在操作数据库之前进行关闭不可用连接操作。

 

编写装饰器代码

 

编写实现代码前,我们先看下Django相关源码

 

Django-2.0.13\django\db\__init__.py

...略

 

# Register an event to reset saved queries when a Django request is started.

def reset_queries(**kwargs):

   for conn in connections.all():

       conn.queries_log.clear()

 

 

signals.request_started.connect(reset_queries)

 

 

# Register an event to reset transaction state and close connections past

# their lifetime.

def close_old_connections(**kwargs):

   for conn in connections.all():

       conn.close_if_unusable_or_obsolete()

 

 

signals.request_started.connect(close_old_connections)

signals.request_finished.connect(close_old_connections)

 

如上英文注释,可知道,开始请求和完成请求都会调用close_old_connections,重置会话事务状态,关闭超过生命周期的连接,所以我们可以参照这个实现自己的装饰器

 

新建wrappers.py

本例中,wrappers.py存放路径:TMP/backend/common/wrappers.py(这里TMP是我的项目名称,backend为新建应用名称)

 

#!/usr/bin/env python

# -*- coding:utf-8 -*-

 

__author__ = 'shouke'

 

'''

自定义装饰器

'''

 

from django.db import close_old_connections

 

def close_old_database_connections(func):

   '''自定义decorator,用来装饰使用数据库操作函数'''

   def wrapper(*args, **kwargs):

       close_old_connections()

       return func(*args, **kwargs)

 

   return wrapper

 

 

 

使用装饰器

 

#!/usr/bin/env python

# -*- coding:utf-8 -*-

 

__author__ = 'shouke'

 

 

from backend.common.wrappers import close_old_database_connections

 

@close_old_database_connections

def gather_zengtao_group_defect_trend_data():

   # ...Django orm数据库操作

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
95 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
|
4月前
|
搜索推荐 前端开发 数据可视化
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
本文介绍了一个基于Python协同过滤算法的旅游景点推荐系统,该系统采用Django框架、MySQL数据库、Bootstrap前端和echarts数据可视化技术,旨在为用户提供个性化的旅游推荐服务,提升用户体验和旅游市场增长。
408 9
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
|
4月前
|
搜索推荐 前端开发 算法
基于用户画像及协同过滤算法的音乐推荐系统,采用Django框架、bootstrap前端,MySQL数据库
本文介绍了一个基于用户画像和协同过滤算法的音乐推荐系统,使用Django框架、Bootstrap前端和MySQL数据库构建,旨在为用户提供个性化的音乐推荐服务,提高推荐准确性和用户满意度。
319 7
基于用户画像及协同过滤算法的音乐推荐系统,采用Django框架、bootstrap前端,MySQL数据库
|
4月前
|
存储 关系型数据库 MySQL
基于python django 医院管理系统,多用户功能,包括管理员、用户、医生,数据库MySQL
本文介绍了一个基于Python Django框架开发的医院管理系统,该系统设计了管理员、用户和医生三个角色,具备多用户功能,并使用MySQL数据库进行数据存储和管理。
186 4
基于python django 医院管理系统,多用户功能,包括管理员、用户、医生,数据库MySQL
|
3月前
|
数据库 Python
django中数据库外键可以自定义名称吗
django中数据库外键可以自定义名称吗
|
3月前
|
关系型数据库 MySQL 数据库连接
9-13|django.db.utils.OperationalError: (2006, 'Server has gone away') 报错
9-13|django.db.utils.OperationalError: (2006, 'Server has gone away') 报错
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
3月前
|
关系型数据库 MySQL 数据库
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
232 0
|
4月前
|
安全 数据库 数据安全/隐私保护
|
4月前
|
数据采集 关系型数据库 MySQL
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
49 1