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选择排序算法的实现代码
Nov 21 Python
python抓取某汽车网数据解析html存入excel示例
Dec 04 Python
Python中使用urllib2模块编写爬虫的简单上手示例
Jan 20 Python
Python实现图片转字符画的示例代码
Aug 21 Python
Python实现的单向循环链表功能示例
Nov 10 Python
Python PyCharm如何进行断点调试
Jul 05 Python
利用python计算windows全盘文件md5值的脚本
Jul 27 Python
Python SELENIUM上传文件或图片实现过程
Oct 28 Python
Keras中的多分类损失函数用法categorical_crossentropy
Jun 11 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
Nov 06 Python
scrapy在python爬虫中搭建出错的解决方法
Nov 22 Python
virtualenv隔离Python环境的问题解析
Jun 21 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
很温暖很温暖的Lester Young
2021/03/03 冲泡冲煮
详解PHP显示MySQL数据的三种方法
2008/06/05 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
如何利用http协议发布博客园博文评论
2015/08/03 PHP
php生成Android客户端扫描可登录的二维码
2016/05/13 PHP
PHP自定义函数获取汉字首字母的方法
2016/12/01 PHP
利用PHP判断文件是否为图片的方法总结
2017/01/06 PHP
PHP封装请求类实例分析【基于Yii框架】
2019/10/17 PHP
JavaScript 获得选中文本内容的方法
2009/02/15 Javascript
jQuery EasyUI中对表格进行编辑的实现代码
2010/06/10 Javascript
基于node.js的快速开发透明代理
2010/12/25 Javascript
JQuery将文本转化成JSON对象需要注意的问题
2011/05/09 Javascript
js取消单选按钮选中并判断对象是否为空
2013/11/14 Javascript
浅析JavaScript中的隐式类型转换
2013/12/05 Javascript
Javascript常用小技巧汇总
2015/06/24 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
2015/12/10 Javascript
基于javascript实现彩票随机数生成(简单版)
2020/04/17 Javascript
JavaScript编写Chrome扩展实现与浏览器的交互及时间通知
2016/05/16 Javascript
JS原型与原型链的深入理解
2017/02/15 Javascript
Vue自定义事件(详解)
2017/08/19 Javascript
antd组件Upload实现自己上传的实现示例
2018/12/18 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
Mpvue中使用Vant Weapp组件库的方法步骤
2019/05/16 Javascript
JS实现商城秒杀倒计时功能(动态设置秒杀时间)
2019/12/12 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
2020/06/05 Javascript
JavaScript Image对象实现原理实例解析
2020/08/26 Javascript
基于Vue+Webpack拆分路由文件实现管理
2020/11/16 Javascript
vue中配置scss全局变量的步骤
2020/12/28 Vue.js
使用简单工厂模式来进行Python的设计模式编程
2016/03/01 Python
详解python的ORM中Pony用法
2018/02/09 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
2019/01/23 Python
python十进制转二进制的详解
2020/02/07 Python
初中三年毕业生的自我评价分享
2014/02/14 职场文书
市场开发与营销专业求职信范文
2014/05/01 职场文书
2015年防灾减灾工作总结
2015/07/24 职场文书
2016年安康杯竞赛活动总结
2016/04/05 职场文书