获取Django框架ORM查询执行的SQL语句实现方法分析
本文详细解析了在Django框架中获取ORM生成的原生SQL语句的五种方法。包括通过数据库日志、Query对象属性、DEBUG模式配置、第三方中间件以及查看connections查询记录等方式。重点推荐了基于中间件的插拔式方案,适用于开发调试阶段,帮助开发者验证查询效率与正确性。
Django ORM SQL语句获取方法概述
本文详细介绍在Django框架中获取ORM查询所执行SQL语句的具体实现方法,供读者参考学习。
使用Django ORM可以便捷地构建各类数据查询,但在实际开发中,有时需要验证生成的SQL语句是否符合预期。为此,本文总结了以下几种有效的检查方式。
通过数据库日志查看
第一种方法是通过数据库的跟踪日志查看查询语句。例如,MySQL支持配置将SQL语句打印到日志中。不过,这种方式通常不被推荐,仅在无法使用其他手段时作为备选方案。
利用Query对象方法
第二种方法是利用Django Query对象提供的方法。具体操作示例如下:
queryset = MyModel.objects.all()
print 'query sql: ' + str(queryset .query)
#result:
在PyDev环境中对Django进行调试时,可以通过截图直观地查看执行结果,确保查询逻辑正确。

配置DEBUG模式获取
第三种方法是修改settings配置中的 debug=True 参数。开启该设置后,可以通过特定方式获取执行的SQL语句。
from django.db import connections
connections['default'].queries
获取的结果格式通常如下所示:
[{u'time': u'0.000', u'sql': u'Select COUNT(*) FROM `my_article` Where `my_article`.`category` = 68 '}]
使用第三方中间件
第四种方法是使用第三方提供的中间件来实现SQL打印功能,具体参考链接:https://djangosnippets.org/snippets/290/。
from django.db import connection
from django.conf import settings
import os
def terminal_width():
"""
Function to compute the terminal width.
WARNING: This is not my code, but I've been using it forever and
I don't remember where it came from.
"""
width = 0
try:
import struct, fcntl, termios
s = struct.pack('HHHH', 0, 0, 0, 0)
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
width = struct.unpack('HHHH', x)[1]
except:
pass
if width <= 0:
try:
width = int(os.environ['COLUMNS'])
except:
pass
if width <= 0:
width = 80
return width
class SqlPrintingMiddleware(object):
"""
Middleware which prints out a list of all SQL queries done
for each view that is processed. This is only useful for debugging.
"""
def process_response(self, request, response):
indentation = 2
if len(connection.queries) > 0 and settings.DEBUG:
width = terminal_width()
total_time = 0.0
for query in connection.queries:
nice_sql = query['sql'].replace('"', '').replace(',',', ')
sql = "\033[1;31m[%s]\033[0m %s" % (query['time'], nice_sql)
total_time = total_time + float(query['time'])
while len(sql) > width-indentation:
print "%s%s" % (" "*indentation, sql[:width-indentation])
sql = sql[width-indentation:]
print "%s%s\n" % (" "*indentation, sql)
replace_tuple = (" "*indentation, str(total_time))
print "%s\033[1;32m[TOTAL TIME: %s seconds]\033[0m" % replace_tuple
return response
在定义好该中间件后,需要在settings中进行相应的配置以启用它。
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'yihaomen.common.mymiddleware.SqlPrintingMiddleware', # 这是增加的显示sql语句的middleware
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
配置完成后,系统会打印所有执行的SQL语句。这种方式被推荐用于开发环境,因为它具有插拔式特性,无需时可直接移除中间件。需要注意的是,该方案仅适用于Debug模式,对开发者而言已足够使用,生产环境通常无需开启。
希望本文所述内容能帮助读者更好地掌握Django框架下的Python程序设计技巧。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













