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创建线程示例
May 06 Python
python静态方法实例
Jan 14 Python
Python挑选文件夹里宽大于300图片的方法
Mar 05 Python
python使用BeautifulSoup分析网页信息的方法
Apr 04 Python
Python2.x中文乱码问题解决方法
Jun 02 Python
简介Python设计模式中的代理模式与模板方法模式编程
Feb 02 Python
如何用itertools解决无序排列组合的问题
May 18 Python
python issubclass 和 isinstance函数
Jul 25 Python
windows下python安装pip方法详解
Feb 10 Python
python 实现线程之间的通信示例
Feb 14 Python
解决pycharm 格式报错tabs和space不一致问题
Feb 26 Python
Pandas实现DataFrame的简单运算、统计与排序
Mar 31 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 $_SERVER当前完整url的写法
2009/11/12 PHP
分享8个最佳的代码片段在线测试网站
2013/06/29 PHP
如何在Ubuntu下启动Apache的Rewrite功能
2013/07/05 PHP
ThinkPHP模板Switch标签用法示例
2014/06/30 PHP
PHP文件操作详解
2016/12/30 PHP
PHP封装的mysqli数据库操作类示例
2019/02/16 PHP
解决laravel资源加载路径设置的问题
2019/10/14 PHP
js中判断控件是否存在
2010/08/25 Javascript
超越Jquery_01_isPlainObject分析与重构
2010/10/20 Javascript
php显示当前文件所在的文件以及文件夹所有文件以树形展开
2013/12/13 Javascript
javascript生成json数据简单示例分享
2014/02/14 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
2014/10/22 Javascript
JavaScript中遍历对象的property的3种方法介绍
2014/12/30 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
浅析jQuery 3.0中的Data
2016/06/14 Javascript
原生JS实现列表子元素顺序反转的方法分析
2018/07/02 Javascript
Vue脚手架的简单使用实例
2018/07/10 Javascript
js中console在一行内打印字符串和对象的方法
2019/09/10 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
Python中的默认参数详解
2015/06/24 Python
基于Django模板中的数字自增(详解)
2017/09/05 Python
浅谈python数据类型及类型转换
2017/12/18 Python
python解析多层json操作示例
2019/12/30 Python
python使用matplotlib:subplot绘制多个子图的示例
2020/09/24 Python
python利用tkinter实现图片格式转换的示例
2020/09/28 Python
HTML5中的Web Notification桌面右下角通知功能的实现
2018/04/19 HTML / CSS
检察官就职演讲稿
2014/01/13 职场文书
执行总经理岗位职责
2014/02/03 职场文书
宗教学大学生职业生涯规划范文
2014/02/08 职场文书
校企合作协议书
2014/04/16 职场文书
秋季运动会演讲稿
2014/09/16 职场文书
教师党的群众路线教育实践活动学习心得体会
2014/10/30 职场文书
检讨书模板大全
2015/05/07 职场文书
歼十出击观后感
2015/06/11 职场文书
2016继续教育研修日志
2015/11/13 职场文书
Python操作CSV格式文件的方法大全
2021/07/15 Python