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线程的两种编程方式
Apr 14 Python
Python创建对称矩阵的方法示例【基于numpy模块】
Oct 12 Python
Python实现1-9数组形成的结果为100的所有运算式的示例
Nov 03 Python
python实现学生管理系统
Jan 11 Python
python使用pil库实现图片合成实例代码
Jan 20 Python
Python迭代器与生成器用法实例分析
Jul 09 Python
如何用C代码给Python写扩展库(Cython)
May 17 Python
windows10下安装TensorFlow Object Detection API的步骤
Jun 13 Python
Django的Modelforms用法简介
Jul 27 Python
python3图片文件批量重命名处理
Oct 31 Python
python常用运维脚本实例小结
Feb 14 Python
改变 Python 中线程执行顺序的方法
Sep 24 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中记录用户访问过的产品,在cookie记录产品id,id取得产品信息
2011/05/04 PHP
php实现批量下载百度云盘文件例子分享
2014/04/10 PHP
php中explode的负数limit用法分析
2015/02/27 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
浅谈javascript的数据类型检测
2010/07/10 Javascript
一个JavaScript函数把URL参数解析成Json对象
2014/09/24 Javascript
javascript常用的方法分享
2015/07/01 Javascript
jQuery的Ajax用户认证和注册技术实例教程(附demo源码)
2015/12/08 Javascript
实现easyui的datagrid导出为excel的示例代码
2016/11/10 Javascript
详解自动生成博客目录案例
2016/12/09 Javascript
JS作用域深度解析
2016/12/29 Javascript
BootStrap栅格系统、表单样式与按钮样式源码解析
2017/01/20 Javascript
微信小程序之前台循环数据绑定
2017/08/18 Javascript
vue+swiper实现组件化开发的实例代码
2017/10/26 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
js 实现watch监听数据变化的代码
2019/10/13 Javascript
Python用GET方法上传文件
2015/03/10 Python
Python文件右键找不到IDLE打开项解决办法
2015/06/08 Python
Python实现屏幕截图的两种方式
2018/02/05 Python
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
python贪吃蛇游戏代码
2020/04/18 Python
python实现一个函数版的名片管理系统过程解析
2019/08/27 Python
Ted Baker英国官网:男士和女士服装及配件
2017/03/13 全球购物
Footshop乌克兰:运动鞋的最大选择
2019/12/01 全球购物
德国便宜的宠物店:Brekz.de
2020/10/23 全球购物
新闻网站实习自我鉴定
2013/09/25 职场文书
电焊工工作岗位职责
2014/02/06 职场文书
集中整治工作方案
2014/05/01 职场文书
企业演讲稿范文大全
2014/05/20 职场文书
2014年作风建设心得体会
2014/10/22 职场文书
走群众路线学习笔记
2014/11/06 职场文书
承兑汇票转让证明怎么写?
2014/11/30 职场文书
惹女朋友生气检讨书
2015/05/06 职场文书
护士岗位竞聘书
2015/09/15 职场文书
2015年街道办事处团委工作总结
2015/10/14 职场文书
Docker官方工具docker-registry案例演示
2022/04/13 Servers