django执行原始查询sql,并返回Dict字典例子


Posted in Python onApril 01, 2020

很多时候执行sql语句,数据比django的model来的快,但并不想关心返回的字段,例如你可以执行:select * from product这种sql,这里个方法将会返回与数据库列名相同的键值对 ,格式是这样子的:

result = [{“id”:1,”name”:”product1”},{“id”:2,”name”:”product2”}]

当然你还可以

import json
json.dumps(result )

返回一串json数据,是不是很完美。。。

# coding:utf-8
from django.db import connection, transaction

'''执行django原始sql语句 并返回一个数组对象'''
def executeQuery(sql):
 cursor = connection.cursor() # 获得一个游标(cursor)对象
 cursor.execute(sql)
 rawData = cursor.fetchall()
 print rawData
 col_names = [desc[0] for desc in cursor.description]
 print col_names

 result = []
 for row in rawData:
  objDict = {}
  # 把每一行的数据遍历出来放到Dict中
  for index, value in enumerate(row):
  print index, col_names[index], value
  objDict[col_names[index]] = value

  result.append(objDict)

 return result

补充知识:重写django的mysql驱动实现原生sql语句查询返回字典类型数据

在使用django的时候,有些需求需要特别高的查询效率,所以需要使用原生的sql语句查询,但是查询结果一般是一个元组嵌套元组。为了处理方便,需要从数据库查询后直接返回字典类型的数据。

这里使用的方法是继承django.db.backends.mysql驱动

首先在django项目下创建一个mysql文件夹,然后在这个文件夹下创建base.py。

base.py

from django.db.backends.mysql import base
from django.db.backends.mysql import features
from django.utils.functional import cached_property
 
class DatabaseFeatures(features.DatabaseFeatures):
 @cached_property
 def is_sql_auto_is_null_enabled(self):
  with self.connection.cursor() as cursor:
   cursor.execute('SELECT @@SQL_AUTO_IS_NULL')
   result = cursor.fetchone()
   return result and result['@@SQL_AUTO_IS_NULL'] == 1
 
 
class DatabaseWrapper(base.DatabaseWrapper):
 features_class = DatabaseFeatures
 
 def create_cursor(self, name=None):
  cursor = self.connection.cursor(self.Database.cursors.DictCursor)
  return base.CursorWrapper(cursor)
 
 @cached_property
 def mysql_server_info(self):
  with self.temporary_connection() as cursor:
   cursor.execute('SELECT VERSION()')
   return cursor.fetchone()['VERSION()']

最后在django项目的settings.py文件里修改数据库配置的数据库引擎

DATABASES = {
 'default': {
  'ENGINE': 'Test.mysql', # 指定数据库驱动为刚刚创建的mysql文件夹
  'NAME': 'test', # 指定的数据库名
  'USER': 'root', # 数据库登录的用户名
  'PASSWORD': '123456', # 登录数据库的密码
  'HOST': '127.0.0.1',
  'PORT': '3306', # 数据库服务器端口,mysql默认为3306
  'DATABASE_OPTIONS': {
   'connect_timeout': 60,
   'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
   'charset': 'utf8mb4',
  },
 }
}

测试

from django.db import connections
 
def f():
 search_sql = "SELECT propertyphotoid,propertyid,alykey FROM lansi_architecture_data.propertyphoto limit 0,5"
 cursor = connections['default'].cursor()
 try:
  cursor.execute(search_sql)
  rows = cursor.fetchall()
 except Exception as e:
  print(e)
  rows = 1
 
 print(rows)

输出结果

[{'propertyphotoid': 27, 'propertyid': 0, 'alykey': '123456'}, {'propertyphotoid': 28, 'propertyid': 10837, 'alykey': 'Property/6113/207504A1-AC65-4E3B-BE86-538B3807D364'}, {'propertyphotoid': 29, 'propertyid': 6113, 'alykey': 'Property/6113/357A4EAE-750A-4F59-AF01-271B4225CFBD'}, {'propertyphotoid': 31, 'propertyid': 6113, 'alykey': 'Property/6113/6DF1A2C1-F54C-4462-8363-619806A2F085'}, {'propertyphotoid': 36, 'propertyid': 6113, 'alykey': 'Property/6113/572CB245-ABC0-4FD6-8353-729EBD5E5D46'}]

源码解析:

django.db.utils.ConnectionHandler的__getitem__方法

django执行原始查询sql,并返回Dict字典例子

获取连接对象的游标是由DatabaseWrapper类的create_cursor返回的。所以只需要重写create_cursor方法,就可以更改游标返回的数据类型了。

django.db.backends.mysql.base.DatabaseWrapper类中的create_cursor方法如下:

def create_cursor(self, name=None):
  cursor = self.connection.cursor()
  return CursorWrapper(cursor)

到这里,理论上已经完成了重写目标,但是在测试的时候出错了,在django.db.backends.mysql.features.DatabaseFeatures里的is_sql_auto_is_null_enabled方法报出KeyError的错误。

@cached_property
 def is_sql_auto_is_null_enabled(self):
  with self.connection.cursor() as cursor:
   cursor.execute('SELECT @@SQL_AUTO_IS_NULL')
   result = cursor.fetchone()
   return result and result[0] == 1

原因是is_sql_auto_is_null_enabled方法使用了重写后的游标,cursor.execute('SELECT @@SQL_AUTO_IS_NULL')返回的结果不是元组,而是一个字典。所以result[0]会报出KeyError的错误。重写is_sql_auto_is_null_enabled方法把result[0]改成result['@@SQL_AUTO_IS_NULL']就可以了.

最后还需要把DatabaseWrapper类里的features_class赋值为重写后的DatabaseFeatures类。

以上这篇django执行原始查询sql,并返回Dict字典例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现从订阅源下载图片的方法
Mar 11 Python
Python验证码识别处理实例
Dec 28 Python
Google开源的Python格式化工具YAPF的安装和使用教程
May 31 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
Nov 20 Python
python最长回文串算法
Jun 04 Python
解决pycharm py文件运行后停止按钮变成了灰色的问题
Nov 29 Python
django url到views参数传递的实例
Jul 19 Python
利用 Flask 动态展示 Pyecharts 图表数据方法小结
Sep 04 Python
python使用smtplib模块发送邮件
Dec 17 Python
Python机器学习之底层实现KNN
Jun 20 Python
python机器学习创建基于规则聊天机器人过程示例详解
Nov 02 Python
分享python函数常见关键字
Apr 26 Python
python 日志 logging模块详细解析
Mar 31 #Python
django迁移文件migrations的实现
Mar 31 #Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
Mar 31 #Python
浅谈Django中的QueryDict元素为数组的坑
Mar 31 #Python
Python + selenium + crontab实现每日定时自动打卡功能
Mar 31 #Python
python实现udp聊天窗口
Mar 31 #Python
浅谈在django中使用filter()(即对QuerySet操作)时踩的坑
Mar 31 #Python
You might like
编写PHP的安全策略
2006/10/09 PHP
php UTF8 文件的签名问题
2009/10/30 PHP
微信公众平台消息接口校验与消息接口响应实例
2014/12/23 PHP
用php+ajax新建流程(请假、进货、出货等)
2017/06/11 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
2019/10/16 PHP
JavaScript中URL编码函数代码
2011/01/11 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
jquery动态分页效果堪比时光网
2014/09/25 Javascript
jQuery实现仿百度首页滑动伸缩展开的添加服务效果代码
2015/09/09 Javascript
js 连续赋值的简单实现
2016/06/13 Javascript
Easyui的组合框的取值与赋值
2016/10/28 Javascript
详解JavaScript对象的深浅复制
2017/03/30 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
jQuery简单实现根据日期计算星期几的方法
2019/01/09 jQuery
node基于async/await对mysql进行封装
2019/06/20 Javascript
vue父子组件间引用之$parent、$children
2020/05/20 Javascript
从零学python系列之浅谈pickle模块封装和拆封数据对象的方法
2014/05/23 Python
编程语言Python的发展史
2014/09/26 Python
尝试使用Python多线程抓取代理服务器IP地址的示例
2015/11/09 Python
Windows下anaconda安装第三方包的方法小结(tensorflow、gensim为例)
2018/04/05 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
用python3 返回鼠标位置的实现方法(带界面)
2019/07/05 Python
python属于软件吗
2020/06/18 Python
增大python字体的方法步骤
2020/07/05 Python
Python中使用Selenium环境安装的方法步骤
2021/02/22 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
css3如何绘制一个圆圆的loading转圈动画
2018/01/09 HTML / CSS
【魔兽争霸3重制版】原版画面与淬火MOD画面对比
2021/03/26 魔兽争霸
优秀应届毕业生自荐信
2013/11/16 职场文书
简历中求职的个人自我评价
2013/12/03 职场文书
幼儿园保育员辞职信
2014/01/12 职场文书
学生党支部先进事迹
2014/02/04 职场文书
专升本学生毕业自我鉴定
2014/10/04 职场文书
个人授权委托书范本格式
2014/10/12 职场文书
关于法制教育的宣传语
2015/07/13 职场文书