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基于mysql实现的简单队列以及跨进程锁实例详解
Jul 07 Python
Python open()文件处理使用介绍
Nov 30 Python
在Python的Django框架中为代码添加注释的方法
Jul 16 Python
Python实现将数据写入netCDF4中的方法示例
Aug 30 Python
Python实现二维曲线拟合的方法
Dec 29 Python
Python 编程速成(推荐)
Apr 15 Python
python numpy之np.random的随机数函数使用介绍
Oct 06 Python
Python drop方法删除列之inplace参数实例
Jun 27 Python
Python分析最近大火的网剧《隐秘的角落》
Jul 02 Python
Python使用xlrd实现读取合并单元格
Jul 09 Python
python 爬虫如何正确的使用cookie
Oct 27 Python
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
Jun 08 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
当海贼王变成JOJO风
2020/03/02 日漫
WampServer下安装多个版本的PHP、mysql、apache图文教程
2015/01/07 PHP
php上传文件问题汇总
2015/01/30 PHP
PHP基于yii框架实现生成ICO图标
2015/11/13 PHP
PHP常用函数总结(180多个)
2016/12/25 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
jQuery帮助之CSS尺寸(五)outerHeight、outerWidth
2009/11/14 Javascript
JavaScript如何从listbox里同时删除多个项目
2013/10/12 Javascript
JQuery学习总结【二】
2016/12/01 Javascript
工厂模式在JS中的实践
2017/01/18 Javascript
vue2.0在没有dev-server.js下的本地数据配置方法
2018/02/23 Javascript
Vue之Vue.set动态新增对象属性方法
2018/02/23 Javascript
node省市区三级数据性能测评实例分析
2019/11/06 Javascript
Vue如何将页面导出成PDF文件
2020/08/17 Javascript
vue打开子组件弹窗都刷新功能的实现
2020/09/21 Javascript
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
Python数据结构之Array用法实例
2014/10/09 Python
Python的Django框架中TEMPLATES项的设置教程
2015/05/29 Python
Python引用模块和查找模块路径
2016/03/17 Python
用pandas按列合并两个文件的实例
2018/04/12 Python
python利用smtplib实现QQ邮箱发送邮件
2020/05/20 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
2019/08/01 Python
Python计算不规则图形面积算法实现解析
2019/11/22 Python
Django异步任务线程池实现原理
2019/12/17 Python
pyautogui自动化控制鼠标和键盘操作的步骤
2020/04/01 Python
详解pandas获取Dataframe元素值的几种方法
2020/06/14 Python
详解HTML5 LocalStorage 本地存储
2016/12/23 HTML / CSS
国际商务专业学生个人的自我评价
2013/09/28 职场文书
书法兴趣小组活动总结
2014/07/07 职场文书
学生实习证明模板汇总
2014/09/25 职场文书
2014年镇党建工作汇报材料
2014/11/02 职场文书
教师党员自我评价2015
2015/03/04 职场文书
张丽莉观后感
2015/06/16 职场文书
幼儿园庆元旦主持词
2015/07/06 职场文书
大学开学感言
2015/08/01 职场文书
Apache Calcite 实现方言转换的代码
2021/04/24 Servers