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实现自动更换ip的方法
May 05 Python
简介二分查找算法与相关的Python实现示例
Aug 26 Python
Python自动发邮件脚本
Mar 31 Python
python 中的int()函数怎么用
Oct 17 Python
Windows 64位下python3安装nltk模块
Sep 19 Python
Django media static外部访问Django中的图片设置教程
Apr 07 Python
python实现处理mysql结果输出方式
Apr 09 Python
keras-siamese用自己的数据集实现详解
Jun 10 Python
PyInstaller运行原理及常用操作详解
Jun 13 Python
python 多线程中join()的作用
Oct 29 Python
python3中布局背景颜色代码分析
Dec 01 Python
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
Apr 06 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 删除文件与文件夹操作 unlink()与rmdir()这两个函数的使用
2011/07/17 PHP
PHP开发微信支付的代码分享
2014/05/25 PHP
PHP判断表达式中括号是否匹配的简单实例
2016/10/22 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
jQuery实现图片信息的浮动显示实例代码
2013/08/28 Javascript
屏蔽相应键盘按钮操作
2014/03/10 Javascript
javascript中CheckBox全选终极方案
2015/05/20 Javascript
JS实现可关闭的对联广告效果代码
2015/09/14 Javascript
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
2016/04/01 Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
2016/09/04 Javascript
vue组件实现进度条效果
2018/06/06 Javascript
深入浅析var,let,const的异同点
2018/08/07 Javascript
前端防止用户重复提交js实现代码示例
2018/09/07 Javascript
微信小程序自定义tabBar组件开发详解
2020/09/24 Javascript
Node.js API详解之 net模块实例分析
2020/05/18 Javascript
[02:47]DOTA2亚洲邀请赛 HR战队出场宣传片
2015/02/07 DOTA
Python入门篇之列表和元组
2014/10/17 Python
Python Web框架Flask中使用新浪SAE云存储实例
2015/02/08 Python
详解Python中的元组与逻辑运算符
2015/10/13 Python
Pyhton中单行和多行注释的使用方法及规范
2016/10/11 Python
python re模块findall()函数实例解析
2018/01/19 Python
Python中pip更新和三方插件安装说明
2018/07/08 Python
python3 中文乱码与默认编码格式设定方法
2018/10/31 Python
python将txt文件读取为字典的示例
2018/12/22 Python
使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
2019/09/06 Python
Python定时任务APScheduler原理及实例解析
2020/05/30 Python
深入解析HTML5 Canvas控制图形矩阵变换的方法
2016/03/24 HTML / CSS
优质有机椰子产品:Dr. Goerg
2019/09/24 全球购物
公司联欢晚会主持词
2014/03/22 职场文书
《新型玻璃》教学反思
2014/04/13 职场文书
大队干部竞选演讲稿
2014/04/28 职场文书
人民调解员培训方案
2014/06/05 职场文书
慰问信范文
2015/02/14 职场文书
springboot项目以jar包运行的操作方法
2021/06/30 Java/Android