zoukankan      html  css  js  c++  java
  • Django 自定义装饰器解决MySQL server has gone away错误

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

    by:授客 QQ1033553122

     

    测试环境

    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.13djangodb\__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数据库操作

  • 相关阅读:
    不同数据类型在不同编译器下字节大小
    gbk/utf8/gb2312 编码中汉字字母数字所占字节数
    剑指Offer-12 矩阵中的路径
    螺旋矩阵(数组)问题(网易考点)
    C++ 多继承导致的指针偏移问题
    面试题--链表实现插入排序
    C++ 二叉树的深度优先遍历(前中后序)以及广度优先遍历
    (转)软连接和硬链接作用以及区别
    TCP/IP网络五层结构理解以及数据传输流程的理解图示
    常考知识点:进程与线程,多进程与多线程
  • 原文地址:https://www.cnblogs.com/shouke/p/13514046.html
Copyright © 2011-2022 走看看