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中基础的socket编程实战攻略
Jun 01 Python
基于python中的TCP及UDP(详解)
Nov 06 Python
python数字图像处理之高级形态学处理
Apr 27 Python
python+pandas分析nginx日志的实例
Apr 28 Python
Python实现的求解最小公倍数算法示例
May 03 Python
详解django自定义中间件处理
Nov 21 Python
Python函数装饰器常见使用方法实例详解
Mar 30 Python
通过实例简单了解Python中yield的作用
Dec 11 Python
python实现名片管理器的示例代码
Dec 17 Python
Django 实现对已存在的model进行更改
Mar 28 Python
python爬虫beautifulsoup解析html方法
Dec 07 Python
Matlab如何实现矩阵复制扩充
Jun 02 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
不用iconv库的gb2312与utf-8的互换函数
2006/10/09 PHP
php Undefined index和Undefined variable的解决方法
2008/03/27 PHP
php实现的简单日志写入函数
2015/03/31 PHP
php数组随机排序实现方法
2015/06/13 PHP
php安装扩展mysqli的实现步骤及报错解决办法
2017/09/23 PHP
漂亮的提示信息(带箭头)
2007/03/21 Javascript
JavaScript 继承详解(四)
2009/07/13 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
jQuery实现页面下拉100像素出现悬浮窗口的方法
2016/09/05 Javascript
浅谈JQ中mouseover和mouseenter的区别
2016/09/13 Javascript
javascript滚轮控制模拟滚动条
2016/10/19 Javascript
详解Node.js中的Async和Await函数
2018/02/22 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
2019/01/09 jQuery
Vue核心概念Action的总结
2019/01/18 Javascript
uni-app 组件里面获取元素宽高的实现
2019/12/27 Javascript
javascript History对象原理解析
2020/02/17 Javascript
微信小程序自定义纯净模态框(弹出框)的实例代码
2020/03/09 Javascript
[05:45]Ti4观战指南(下)
2014/07/07 DOTA
[01:25:33]完美世界DOTA2联赛PWL S3 INK ICE vs Magma 第二场 12.20
2020/12/23 DOTA
python 合并文件的具体实例
2013/08/08 Python
Python的Django框架中的select_related函数对QuerySet 查询的优化
2015/04/01 Python
总结用Pdb库调试Python的方式及常用的命令
2016/08/18 Python
在PyCharm环境中使用Jupyter Notebook的两种方法总结
2018/05/24 Python
对dataframe数据之间求补集的实例详解
2019/01/30 Python
详解使用Python下载文件的几种方法
2019/10/13 Python
python3中datetime库,time库以及pandas中的时间函数区别与详解
2020/04/16 Python
python matplotlib库的基本使用
2020/09/23 Python
浅析HTML5 Landmark
2020/09/11 HTML / CSS
美国受信赖的教育产品供应商:Nest Learning
2018/06/14 全球购物
学前教育求职自荐信范文
2013/12/25 职场文书
员工拓展培训方案
2014/02/15 职场文书
个人授权委托书模板
2014/09/14 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
Html5页面播放M4a音频文件
2021/03/30 HTML / CSS
redis通过6379端口无法连接服务器(redis-server.exe闪退)
2021/05/08 Redis
Win11电脑显示本地时间与服务器时间不一致怎么解决?
2022/04/05 数码科技