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中使用wxPython开发的一个简易笔记本程序实例
Feb 08 Python
python简单获取本机计算机名和IP地址的方法
Jun 03 Python
django静态文件加载的方法
May 20 Python
好的Python培训机构应该具备哪些条件
May 23 Python
Django项目中model的数据处理以及页面交互方法
May 30 Python
解决Tensorflow安装成功,但在导入时报错的问题
Jun 13 Python
python保存二维数组到txt文件中的方法
Nov 15 Python
nohup后台启动Python脚本,log不刷新的解决方法
Jan 14 Python
Window10下python3.7 安装与卸载教程图解
Sep 30 Python
Keras中的多分类损失函数用法categorical_crossentropy
Jun 11 Python
Python如何给函数库增加日志功能
Aug 04 Python
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
Apr 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
php生成数组的使用示例 php全组合算法
2014/01/16 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
TP5框架安全机制实例分析
2020/04/05 PHP
JavaScript中的私有成员
2006/09/18 Javascript
jquery插件jbox使用iframe关闭问题
2009/02/09 Javascript
jquery关于图形报表的运用实现代码
2011/01/06 Javascript
JavaScript运行时库属性一览表
2014/03/14 Javascript
运用JQuery的toggle实现网页加载完成自动弹窗
2014/03/18 Javascript
Jquery 点击按钮自动高亮实现原理及代码
2014/04/25 Javascript
一个简单的jQuery计算器实现了连续计算功能
2014/07/21 Javascript
基于js实现投票的实例代码
2015/08/04 Javascript
用JS写的一个Ajax库(实例代码)
2016/08/06 Javascript
json定义及jquery操作json的方法
2016/09/29 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
vue脚手架搭建项目的兼容性配置详解
2018/07/17 Javascript
基于D3.js实现时钟效果
2018/07/17 Javascript
详解微信小程序的 request 封装示例
2018/08/21 Javascript
使用weixin-java-tools完成微信授权登录、微信支付的示例
2018/09/26 Javascript
微信小程序实现留言板(Storage)
2018/11/02 Javascript
Nodejs模块的调用操作实例分析
2018/12/25 NodeJs
Python基于pandas实现json格式转换成dataframe的方法
2018/06/22 Python
使用python实现mqtt的发布和订阅
2019/05/05 Python
python 实现视频 图像帧提取
2019/12/10 Python
简单了解django处理跨域请求最佳解决方案
2020/03/25 Python
解决windows下python3使用multiprocessing.Pool出现的问题
2020/04/08 Python
CSS3田字格列表的样式编写方法
2018/11/22 HTML / CSS
车间统计员岗位职责
2014/01/05 职场文书
职工运动会感言
2014/02/07 职场文书
学校后勤岗位职责
2014/02/19 职场文书
无财产离婚协议书范本
2014/10/28 职场文书
医学生自荐信范文
2015/03/05 职场文书
如何写新闻稿
2015/07/18 职场文书
基于Python实现流星雨效果的绘制
2022/03/18 Python
redis protocol通信协议及使用详解
2022/07/15 Redis