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实现在Linux系统下更改当前进程运行用户
Feb 04 Python
python中sleep函数用法实例分析
Apr 29 Python
在Python中处理字符串之ljust()方法的使用简介
May 19 Python
在Python中操作列表之list.extend()方法的使用
May 20 Python
Python3学习笔记之列表方法示例详解
Oct 06 Python
Python常用的json标准库
Feb 19 Python
python实现支付宝转账接口
May 07 Python
对python中的*args与**kwgs的含义与作用详解
Aug 28 Python
Python的赋值、深拷贝与浅拷贝的区别详解
Feb 12 Python
jupyter note 实现将数据保存为word
Apr 14 Python
python模拟斗地主发牌
Apr 22 Python
python GUI计算器的实现
Oct 09 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
eAccelerator的安装与使用详解
2013/06/13 PHP
PHP+mysql实现从数据库获取下拉树功能示例
2017/01/06 PHP
解决出现SoapFault (looks like we got no XML document)的问题
2017/06/24 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
用javascript操作xml
2006/11/04 Javascript
Javascript里使用Dom操作Xml
2007/01/22 Javascript
ie 调试javascript的工具
2009/04/29 Javascript
JQuery Ajax 跨域访问的解决方案
2010/03/12 Javascript
分享20多个很棒的jQuery 文件上传插件或教程
2011/09/04 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
2016/04/06 Javascript
vue 微信授权登录解决方案
2018/04/10 Javascript
使用原生js编写一个简单的框选功能方法
2019/05/13 Javascript
vue实现跨域的方法分析
2019/05/21 Javascript
jQuery实现鼠标移入显示蒙版效果
2020/01/11 jQuery
vue通过接口直接下载java生成好的Excel表格案例
2020/10/26 Javascript
jQuery列表动态增加和删除的实现方法
2020/11/05 jQuery
在vue中使用eslint,配合vscode的操作
2020/11/09 Javascript
在elementui中Notification组件添加点击事件实例
2020/11/11 Javascript
JavaScript实现HTML导航栏下拉菜单
2020/11/25 Javascript
[34:44]Liquid vs TNC Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
python3.6利用pyinstall打包py为exe的操作实例
2018/10/31 Python
pycharm运行程序时在Python console窗口中运行的方法
2018/12/03 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
2019/08/08 Python
python-tornado的接口用swagger进行包装的实例
2019/08/29 Python
Python实现一个论文下载器的过程
2021/01/18 Python
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
最新大学职业规划书范文
2013/12/30 职场文书
青春无悔演讲稿
2014/05/08 职场文书
优秀团员个人总结
2015/02/26 职场文书
从严治党主题教育活动总结
2015/05/07 职场文书
驳回起诉裁定书
2015/05/19 职场文书
军训结束新闻稿
2015/07/17 职场文书
2016年大学生社区服务活动总结
2016/04/06 职场文书
导游词之无锡梅园
2019/11/28 职场文书