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 17 Python
python使用Apriori算法进行关联性解析
Dec 21 Python
Python线性回归实战分析
Feb 01 Python
使用python的pexpect模块,实现远程免密登录的示例
Feb 14 Python
Python3.5多进程原理与用法实例分析
Apr 05 Python
详解用python生成随机数的几种方法
Aug 04 Python
解决pyshp UnicodeDecodeError的问题
Dec 06 Python
Python实现鼠标自动在屏幕上随机移动功能
Mar 14 Python
Python爬虫爬取微信朋友圈
Aug 06 Python
python安装sklearn模块的方法详解
Nov 28 Python
python中reload重载实例用法
Dec 15 Python
Python 里最强的地图绘制神器
Mar 01 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
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
php将数组存储为文本文件方法汇总
2015/10/28 PHP
PHP单例模式简单用法示例
2017/06/23 PHP
Yii框架安装简明教程
2020/05/15 PHP
Ucren Virtual Desktop V2.0
2006/11/07 Javascript
JS IE和FF兼容性问题汇总
2009/02/09 Javascript
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
2010/07/29 Javascript
JavaScript实现多维数组的方法
2013/11/20 Javascript
JavaScript字符串对象replace方法实例(用于字符串替换或正则替换)
2014/10/16 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
Vue.js实现模拟微信朋友圈开发demo
2017/04/20 Javascript
详解如何解决Vue和vue-template-compiler版本之间的问题
2018/09/17 Javascript
node.js调用C++函数的方法示例
2018/09/21 Javascript
vue-cli 3 全局过滤器的实例代码详解
2019/06/03 Javascript
微信自定义分享链接信息(标题,图片和内容)实现过程详解
2019/09/04 Javascript
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
Python3 单行多行万能正则匹配方法
2019/01/07 Python
如何解决flask修改静态资源后缓存文件不能及时更改问题
2020/08/02 Python
pytorch使用horovod多gpu训练的实现
2020/09/09 Python
Windows环境下Python3.6.8 importError: DLLload failed:找不到指定的模块
2020/11/01 Python
css3 条纹化和透明化表格Firefox下测试成功
2014/04/15 HTML / CSS
蔻驰法国官网:COACH法国
2018/11/14 全球购物
将一个数的从第5位开始的7个数取出,其余位置0
2016/05/26 面试题
个人教师自我评价范文
2013/12/02 职场文书
工业自动化毕业生自荐信范文
2014/01/04 职场文书
餐饮业经理竞聘演讲稿
2014/01/14 职场文书
3的组成教学反思
2014/04/30 职场文书
股东授权委托书范文
2014/09/13 职场文书
出售房屋委托书范本
2014/09/24 职场文书
干部作风整顿个人剖析材料
2014/10/06 职场文书
会议欢迎词范文
2015/01/27 职场文书
企业介绍信范文
2015/01/30 职场文书
《中华上下五千年》读后感3篇
2019/11/29 职场文书
Python办公自动化之Excel(中)
2021/05/24 Python
Pytorch中Softmax和LogSoftmax的使用详解
2021/06/05 Python
Python socket如何解析HTTP请求内容
2022/02/12 Python