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基于jieba库进行简单分词及词云功能实现方法
Jun 16 Python
Python 运行.py文件和交互式运行代码的区别详解
Jul 02 Python
python django model联合主键的例子
Aug 06 Python
python 字典的打印实现
Sep 26 Python
python爬虫 正则表达式解析
Sep 28 Python
详解opencv中画圆circle函数和椭圆ellipse函数
Dec 27 Python
Anaconda的安装及其环境变量的配置详解
Apr 22 Python
Python叠加矩形框图层2种方法及效果
Jun 18 Python
python中关于数据类型的学习笔记
Jul 19 Python
python 多线程死锁问题的解决方案
Aug 25 Python
PIP和conda 更换国内安装源的方法步骤
Sep 21 Python
Python 恐龙跑跑小游戏实现流程
Feb 15 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从给定url获取文件扩展名的方法
2015/03/14 PHP
基于PHP如何把汉字转化为拼音
2015/12/11 PHP
PHP实现微信网页授权开发教程
2016/01/19 PHP
详解PHP 7.4 中数组延展操作符语法知识点
2019/07/19 PHP
javascript操作字符串的原生方法
2014/12/22 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
Jquery 自定义事件实现发布/订阅的简单实例
2016/06/12 Javascript
前端 Vue.js 和 MVVM 详细介绍
2016/12/29 Javascript
完美实现js拖拽效果 return false用法详解
2017/07/28 Javascript
Vue 2.0入门基础知识之内部指令详解
2017/10/15 Javascript
详解ajax的data参数错误导致页面崩溃
2018/04/30 Javascript
微信小程序 slot踩坑的解决
2019/04/01 Javascript
layui复选框限制选择个数的方法
2019/09/18 Javascript
python获取本地计算机名字的方法
2015/04/29 Python
Python 爬虫多线程详解及实例代码
2016/10/08 Python
Python IDLE 错误:IDLE''s subprocess didn''t make connection 的解决方案
2017/02/13 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
Python里字典的基本用法(包括嵌套字典)
2019/02/27 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
2019/08/05 Python
深入了解Python装饰器的高级用法
2020/08/13 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
Biblibili视频投稿接口分析并以Python实现自动投稿功能
2021/02/05 Python
The Beach People美国:澳洲海滨奢华品牌
2018/07/05 全球购物
波兰在线运动商店:YesSport
2020/07/23 全球购物
澳大利亚人信任的清洁平台,您的私人管家:Jarvis
2020/12/25 全球购物
英国领先的高级美容和在线皮肤诊所:Face the Future
2020/06/17 全球购物
远程研修随笔感言
2014/02/10 职场文书
会计师职业生涯规划范文
2014/02/18 职场文书
优质护理服务演讲稿
2014/05/07 职场文书
出国英文推荐信
2014/05/10 职场文书
日语系毕业求职信
2014/07/27 职场文书
井冈山红色之旅感想
2014/10/07 职场文书
见习报告怎么写
2014/10/31 职场文书
自主招生自荐信范文
2015/03/04 职场文书
煤矿安全生产管理协议书
2016/03/22 职场文书
Java字符串逆序方法详情
2022/03/21 Java/Android