手把手教你用Django执行原生SQL的方法


Posted in Python onFebruary 18, 2021

前言

Hey,各位小伙伴,这次怎么来玩一下,如何使用Django执行原生SQL。

我们都知道,Python在web界的扛把子——Django,可谓是集大成为统一,各种各样的插件、forms组件、model模型、Admin后台等等,后面我会专门出文章娓娓道来,反正就是一个字,NB。

本次就来学一下,如何在Django执行原生语句。

起因

在使用Django时,一般情况下,我们使用Django自带的model查询是没有问题的,基本能满足80%的问题

但是,但是,那20%就不要了吗???肯定不行哎,小孩才做选择

在Django执行原生SQL有以下三种方式

  • extra
  • raw
  • django connection

一般情况下,就以上三种方式

表结构

文件:django_project/app01/models

class Book(models.Model): 
  title = models.CharField(verbose_name="书名", max_length=32) 
  describe = models.TextField(verbose_name="描述") 
  author = models.CharField(verbose_name="作者", max_length=32) 
  publisher = models.CharField(verbose_name="出版社", max_length=32) 
  publisher_date = models.DateField(verbose_name="publisher")

就是一个很简单的图书表

通过admin录入一些数据测试使用

手把手教你用Django执行原生SQL的方法

extra方式

强烈建议,不用学,没毛用

raw方式

这个相比较extra,还是比较有用的,

语法如下

models.表名.objecs.raw(sql) 
models.表名.objecs.raw(sql,[参数1,参数2])

注:如果没有参数,就只写sql语句,如果由参数,后面需要用列表,如图所示

举例

手把手教你用Django执行原生SQL的方法

返回的仍然一个个的Book对象

真正的原生sql方式

上述的,其实还是和django的model有些绑定。但是我就是说,我就是想要原生sql,不要跟任何绑定。

这里说一下,千万不要在django使用pymysql执行原生sql,会发生一些奇怪的问题。一定要导入from django.db import connection执行sql。代码如下:

from django.db import connection 
def book_list(request): 
  # 真正的原生sql, 
  cursor = connection.cursor() 
  print(type(cursor)) 
  cursor.execute("select * from app01_book where id=%s", [1, ]) 
  raw = cursor.fetchall() 
  print(raw)

返回内容如下图所示:

手把手教你用Django执行原生SQL的方法

可以看到,返回的是列表里面套一个个的数组。我就在想,有没有什么办法能将查询出来的sql,直接返回成字典呢?答案是当然可以!

执行原生sql并且返回成dict

我将执行原生sql并且直接返回成字典的方式封装成了两个函数

一个是查询多个,代码如下所示:

def query_all_dict(sql, params=None): 
  ''' 
  查询所有结果返回字典类型数据 
  :param sql: 
  :param params: 
  :return: 
  ''' 
  with connection.cursor() as cursor: 
    if params: 
      cursor.execute(sql, params=params) 
    else: 
      cursor.execute(sql) 
    col_names = [desc[0] for desc in cursor.description] 
    row = cursor.fetchall() 
    rowList = [] 
    for list in row: 
      tMap = dict(zip(col_names, list)) 
      rowList.append(tMap) 
    return rowList

一个是查询一个,代码如下所示:

def query_one_dict(sql, params=None): 
  """ 
  查询一个结果返回字典类型数据 
  :param sql: 
  :param params: 
  :return: 
  """ 
  with connection.cursor() as cursor: 
    if params: 
      cursor.execute(sql, params=params) 
    else: 
      cursor.execute(sql) 
    col_names = [desc[0] for desc in cursor.description] 
    row = cursor.fetchone() 
    tMap = dict(zip(col_names, row)) 
    return tMap

用法如下,直接在视图中调用函数

手把手教你用Django执行原生SQL的方法

返回结果如下,直接是列表套字典格式

手把手教你用Django执行原生SQL的方法

那查询带条件的怎么办哪,其实和pymysql一个样

手把手教你用Django执行原生SQL的方法

返回结果

手把手教你用Django执行原生SQL的方法

但是有个问题,上面的查询,我们明明知道,让只会返回一个值,但是还是返回的是列表套字典格式,似乎不太对呐?

其实上述我写的是两个办法,如果确定就查询一个值,使用query_one_dict方法。

手把手教你用Django执行原生SQL的方法

手把手教你用Django执行原生SQL的方法

上述总结

django中执行原生sql有3种方式,extra,raw,from django.db import connection

其中extra基本没用,raw凑合,但是和models有绑定,connection最灵活,但是默认返回的是[tuple,tuple,tuple,]格式

经过改良,封装出两个方法,query_all_dict,query_one_dict,一个是查询多个,一个是查询单个,并且返回成[dict,dict,dict,]

建议

只使用query_all_dict,query_one_dict

项目代码

django_exec_sql.zip

需要本文完整代码的小伙伴,可以在本公众号后台回复关键字:原生SQL,进行获取。

总结

上述以入门的方式解决了安排了以下如何通过django执行原生sql。

用微笑告诉别人,今天的我比昨天强,今后也一样。

到此这篇关于手把手教你用Django执行原生SQL的方法的文章就介绍到这了,更多相关Django执行原生SQL内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python根据出生日期返回年龄的方法
Mar 26 Python
探究Python多进程编程下线程之间变量的共享问题
May 05 Python
Python中read()、readline()和readlines()三者间的区别和用法
Jul 30 Python
python爬虫之BeautifulSoup 使用select方法详解
Oct 23 Python
Python3实现的Mysql数据库操作封装类
Jun 06 Python
Python get获取页面cookie代码实例
Sep 12 Python
将pip源更换到国内镜像的详细步骤
Apr 07 Python
完美解决python3.7 pip升级 拒绝访问问题
Jul 12 Python
Django Xadmin多对多字段过滤实例
Apr 07 Python
Python插件机制实现详解
May 04 Python
python 实现图像快速替换某种颜色
Jun 04 Python
OpenCV实现常见的四种图像几何变换
Apr 01 Python
python中封包建立过程实例
Feb 18 #Python
python解包用法详解
Feb 17 #Python
python压包的概念及实例详解
Feb 17 #Python
python解包概念及实例
Feb 17 #Python
requests在python中发送请求的实例讲解
Feb 17 #Python
python切片作为占位符使用实例讲解
Feb 17 #Python
Django视图类型总结
Feb 17 #Python
You might like
PHP数组的交集array_intersect(),array_intersect_assoc(),array_inter_key()函数的小问题
2011/05/29 PHP
CentOS 6.2使用yum安装LAMP以及phpMyadmin详解
2013/06/17 PHP
PHP中调用SVN命令更新网站方法
2015/01/07 PHP
PHP微信开发之有道翻译
2016/06/23 PHP
php实现PDO中捕获SQL语句错误的方法
2017/02/16 PHP
详解json在php中的应用
2018/09/30 PHP
js实现连续英文字符自动换行兼容ie6 ie7和firefox
2013/09/06 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
js实现屏幕自适应局部代码分享
2015/01/30 Javascript
元素绑定click点击事件方法
2015/06/08 Javascript
javascript Slip.js实现整屏滑动的手机网页
2015/11/25 Javascript
jQuery实现磁力图片跟随效果完整示例
2016/09/16 Javascript
老生常谈javascript变量的命名规范和注释
2016/09/29 Javascript
JS 实现 ajax 异步浏览器兼容问题
2017/01/21 Javascript
jQuery EasyUI 为Combo,Combobox添加清除值功能的实例
2017/04/13 jQuery
微信小程序三级联动选择器使用方法
2020/05/19 Javascript
vue2.0页面前进刷新回退不刷新的实现方法
2018/07/31 Javascript
JavaScript动态创建二维数组的方法示例
2019/02/01 Javascript
vue鼠标悬停事件实例详解
2019/04/01 Javascript
js 执行上下文和作用域的相关总结
2021/02/08 Javascript
wxpython学习笔记(推荐查看)
2014/06/09 Python
特征脸(Eigenface)理论基础之PCA主成分分析法
2018/03/13 Python
Python英文文本分词(无空格)模块wordninja的使用实例
2019/02/20 Python
Python 多线程其他属性以及继承Thread类详解
2019/08/28 Python
Python selenium 自动化脚本打包成一个exe文件(推荐)
2020/01/14 Python
python3注册全局热键的实现
2020/03/22 Python
详解CSS3的图层阴影和文字阴影效果使用
2016/06/09 HTML / CSS
css3的动画特效之动画序列(animation)
2017/12/22 HTML / CSS
html5读取本地文件示例代码
2014/04/22 HTML / CSS
What's the difference between deep copy and shallow copy? (深拷贝与浅拷贝有什么区别)
2015/11/10 面试题
性能测试工程师的面试题
2015/02/20 面试题
内勤主管岗位职责
2014/04/03 职场文书
开业庆典活动策划方案
2014/09/21 职场文书
私人房屋买卖协议书
2014/10/04 职场文书
新学期开学寄语2016
2015/12/04 职场文书
导游词之镜泊湖
2019/12/09 职场文书