首页 > 编程 > Python > 正文

获取django框架orm query执行的sql语句实现方法分析

2019-11-25 12:42:20
字体:
来源:转载
供稿:网友

本文实例讲述了获取django框架orm query执行的sql语句实现方法。分享给大家供大家参考,具体如下:

利用Django orM 可以很方便的写出很多查询,但有时候,我们需要检查这些利用 orM 生成的 SQL 语句是否正确,就需要检查这些ORM 生成的 原生的SQL 语句是否正确。经过测试有如下几种方法:

1. 通过数据库的跟踪日志,可以看到查询的语句,比如mysql 就可以配置把所有的 SQL 语句打印到日志中,但这种方式并不推荐,只是没有办法的时候才这么做。

2. 利用django Query 提供的方法. 比如:

 queryset = MyModel.objects.all() print 'query sql: ' + str(queryset .query) #result:

我采用pydev 对 django 进行debug, 如下是截图,可以清楚的看到结果:

3. 设置settings 里的 debug=True, 这个时候可以用这种方式来获取

from django.db import connectionsconnections['default'].queries

结果类似如下:

[{u'time': u'0.000', u'sql': u'Select COUNT(*) FROM `my_article` Where `my_article`.`category` = 68 '}]

4. 利用三方提供的middleware 来实现,参考这里: https://djangosnippets.org/snippets/290/

from django.db import connectionfrom django.conf import settingsimport osdef 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 widthclass 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

当然,定义了这个middleware之后,需要修改setting 里的配置

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 语句, 推荐采用这种方式打印 sql 语句,因为比较方便,而且是插拔式的,不需要的时候去掉这个middleware就可以了,不过这只能在debug 模式下使用,对开发者来说足够了,生产环境不需要debug模式。

希望本文所述对大家基于Django框架的Python程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表