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使用any判断一个对象是否为空的方法
Nov 19 Python
python实现监控某个服务 服务崩溃即发送邮件报告
Jun 21 Python
Python中判断子串存在的性能比较及分析总结
Jun 23 Python
opencv python 图像轮廓/检测轮廓/绘制轮廓的方法
Jul 03 Python
Python 继承,重写,super()调用父类方法操作示例
Sep 29 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
Feb 12 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
Apr 01 Python
python可迭代对象去重实例
May 15 Python
Python机器学习算法之决策树算法的实现与优缺点
May 13 Python
Pygame Rect区域位置的使用(图文)
Nov 17 Python
如何用六步教会你使用python爬虫爬取数据
Apr 06 Python
python在package下继续嵌套一个package
Apr 14 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 和 XML: 使用expat函数(二)
2006/10/09 PHP
php正则表达式(regar expression)
2011/09/10 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
javascript结合canvas实现图片旋转效果
2015/05/03 Javascript
Javascript动态创建表格及删除行列的方法
2015/05/15 Javascript
js时间戳转为日期格式的方法
2015/12/28 Javascript
js HTML5 Canvas绘制转盘抽奖
2020/09/13 Javascript
javascript阻止事件冒泡和浏览器的默认行为
2017/01/21 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
详解Angular2响应式表单
2017/06/14 Javascript
jQuery实现IE输入框完成placeholder标签功能的方法
2017/09/20 jQuery
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
node实现登录图片验证码的示例代码
2018/04/20 Javascript
JavaScript中变量提升与函数提升经典实例分析
2018/07/26 Javascript
Koa 中的错误处理解析
2019/04/09 Javascript
javascript用defineProperty实现简单的双向绑定方法
2020/04/03 Javascript
JS实现电脑虚拟键盘打字测试
2020/06/24 Javascript
[04:50]2019DOTA2高校联赛秋季赛四强集锦
2019/12/27 DOTA
python开发之文件操作用法实例
2015/11/13 Python
详解Python的Flask框架中的signals信号机制
2016/06/13 Python
python中的字典操作及字典函数
2018/01/03 Python
Python 2.7中文显示与处理方法
2018/07/16 Python
python2与python3中关于对NaN类型数据的判断和转换方法
2018/10/30 Python
Python使用import导入本地脚本及导入模块的技巧总结
2019/08/07 Python
浅谈Python type的使用
2019/11/19 Python
Python中os模块功能与用法详解
2020/02/26 Python
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
2021/02/20 Python
德国便宜的宠物店:Brekz.de
2020/10/23 全球购物
成龙霸王洗发水广告词
2014/03/14 职场文书
2015年幼儿园元旦游艺活动策划书
2014/12/09 职场文书
辩论赛主持人开场白
2015/05/29 职场文书
实习单位意见
2015/06/04 职场文书
解决goland 导入项目后import里的包报红问题
2021/05/06 Golang
Kubernetes中Deployment的升级与回滚
2022/04/01 Servers
利用Python实时获取steam特惠游戏数据
2022/06/25 Python