django頁面請求sql分析中間件

好久沒有寫博客了,記錄一些東西吧git

寫django程序時因爲直接和django model交互,對sql的操做不是那麼直觀。因此很容易形成一些sql查詢問題。github

如常見的sql分頁位置不正確致使查詢整個表,屢次queryset沒有利用緩存致使屢次sql重複查詢等。以前一直用打印的方式查詢,感受仍是不夠方便。sql

因而有了下面的sql中間件,在本地開發時每次輸出sql的一些簡單分析信息提供參考django

class DjangoSqlInspectMiddleware(object):

    def process_request(self, request):
        self.start_end_chars_dict = {'start_chars': '<' * 20, 'end_chars': '>' * 20}

        self.start = time.time()
        logger.info(os.linesep * 4)
        logger.info('%(start_chars)s sql analyse start %(end_chars)s' % self.start_end_chars_dict)

    def process_response(self, request, response):
        sqltime_list = connection.queries
        pprint.pprint(sqltime_list)

        duplicate_sqltime_dict = defaultdict(int)
        sql_total_time = 0
        max_sqltime, min_sqltime = (None,) * 2
        for st in sqltime_list:
            sql = st['sql']
            sql_total_time += float(st['time'])
            duplicate_sqltime_dict[sql] = duplicate_sqltime_dict[sql] + 1
            if not max_sqltime or not min_sqltime:
                max_sqltime = min_sqltime = st
            else:
                t = st['time']
                if t > max_sqltime['time']:
                    max_sqltime = st
                if t < min_sqltime['time']:
                    min_sqltime = st

        self.end = time.time()
        consume_time = self.end - self.start
        logger.info('[SQL] %s queries, %s SQL time, %s total request time' %
                    (len(duplicate_sqltime_dict), sql_total_time, consume_time))

        logger.info('[MAX TIME]: %s seconds' % (max_sqltime['time'], ))
        logger.info('[MAX TIME SQL]:%s %s' % (os.linesep, max_sqltime['sql']))

        logger.info('[MIN TIME]: %s seconds' % min_sqltime['time'])
        logger.info('[MIN TIME SQL]:%s %s' % (os.linesep, min_sqltime['sql']))

        logger.info('[CHECK DUPLICATE]:')
        for k, v in duplicate_sqltime_dict.iteritems():
            if v > 1:
                logger.info('(%s)' % v + k)
                logger.info('---------------------------------------------')
        logger.info('%(start_chars)s sql analyse end %(end_chars)s' % self.start_end_chars_dict)
        logger.info(os.linesep * 2)
        return response

主要程序如上, 若是感興趣的同窗能夠在github上一塊兒完善或者有更好的方式給予建議哈緩存

https://github.com/lyroge/django-sqlinspectcode

相關文章
相關標籤/搜索