当前位置: 首页 > news >正文

django使用原生SQL查询示例

django使用原生SQL查询示例

实际开发中,在ORM模型查询API不够用或或者数据量比较大的情况下,我们只能使用原始的SQL语句进行查询。

文章目录

  • django使用原生SQL查询示例
      • 1.raw()方法
        • 利用RAW方法执行原生的SQL语句
        • RAW()查询可以查询其他表的数据
        • RAW()方法自动将查询字段映射到模型字段
        • 原生SQL使用参数
      • 2.使用extra方法:
      • 3.直接执行原生SQL
      • 补充:

1.raw()方法

raw()管理器方法用于原始的SQL查询,并返回模型的实例
需要注意的是:raw()语法查询必须包含主键
这个方法执行原始的SQL查询,并返回一个django.db.models.query.RawQuerySet 实例。 这个RawQuerySet 实例可以像一般的QuerySet那样,通过迭代来提供对象实例。

rawQuerySet为惰性查询,只有在使用时才会真正执行

利用RAW方法执行原生的SQL语句

假设现在我们有一个Book与Publish的Model:

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=33)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publisher = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
    
    def __str__(self):
        return self.title

class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=22)
    city = models.CharField(max_length=20)

增加一条测试路由:

url(r'^raw/',views.raw),

然后使用raw 方法查询:

for book_obj in Book.objects.raw('select * from book_book where price>100'):
    print(book_obj)

RAW()查询可以查询其他表的数据

#注意这里必须select id字段,否则会报错
ret = Book.objects.raw('select id,city from book_publish')
for i in ret:
    print(i.id,i.city)

结果是Publish表的id与city:注意必须要select id,否则会报错

RAW()方法自动将查询字段映射到模型字段

还可以通过translations参数指定一个把查询的字段名和ORM对象实例的字段名互相对应的字典:

dic = {'city':'C'}
    ret = Book.objects.raw('select * from book_publish',translations=dic)
    for i in ret:
        print(i.id,i.name,i.C)

原生SQL使用参数

注意不要自己使用字符串格式化拼接SQL语句,防止SQL注入!

dic = {'city':'C'}
ret = Book.objects.raw('select * from book_publish where id > %s',translations=dic,params=[22,])
for i in ret:
    print(i.id,i.name,i.C)

2.使用extra方法:

extra:结果集修改器,一种提供额外查询参数的机制

Book.objects.filter(publisher='广东人员出版社').extra(where=['price>50'])
Book.objects.filter(publisher='广东人员出版社',price__gt=50)
Book.objects.extra(select={'count':'select count(*) from book_publish'})

# 提供额外的参数
ret = models.Book.objects.all().extra(where=['id > %s'], params=['1'], order_by=['-id'])

3.直接执行原生SQL

以上方法都是 基于django模型,很多情况下我们不需要将查询结果映射成模型(model),或者我们需要执行DELETE、 INSERT以及UPDATE操作。
在这些情况下,我们可以直接访问数据库,完全避开模型层。
我们可以直接从django提供的接口中获取数据库连接,然后像使用pymysql模块一样操作数据库。
注意不要自己使用字符串格式化拼接SQL语句,防止SQL注入!

简单示例:

from django.db import connection,connections
# 获取游标对象
cursor = connection.cursor()  #cursor = connections['default'].cursor()
# 使用原生SQL进行查询
cursor.execute(' select * from book_publish where id > %s ',[22])
# 获取所有的数据
ret = cursor.fetchall()
print(ret)

补充:

在不使用默认数据库下,链接配置

import pymysql
from 项目名.settings import DATABASES


class Database_operat(object):
    def __init__(self, database=DATABASES, database_name='default'):
        database_information = database[database_name]
        try:
            self.db = pymysql.connect(host=database_information['HOST'], user=database_information['USER'], port=database_information['PORT'],
                                      password=database_information['PASSWORD'], db=database_information['NAME'])
            self.cur = self.db.cursor()
        except pymysql.err.OperationalError as e:
            print(e)
            print("连接数据库失败")
            return

参考资料:

  • 简书:django中用原生sql查询
  • Django中使用原生SQL的三种方式 CSDN博客
  • Django 数据库查询集合(双下划线连表操作)
  • Django执行原生 SQL 查询
  • 博客园

相关文章:

  • SQL server安装教程
  • python (socket)网络编程与并发
  • Linux安装Anaconda和虚拟环境配置
  • 2021最强Python学习教程,从零基础入门到精通
  • 大前端基础学习笔记
  • go语言开发之旅
  • Docker 入门到精通
  • Linux基础学习笔记
  • Python魔法方法(内置方法)合集
  • Django入门到高阶
  • Django-rest-framework框架学习笔记
  • VUE从入门基础学习笔记
  • uni-app入门基础学习
  • 爬虫学习记录
  • Flask快速入门篇
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 11111111
  • Android开源项目规范总结
  • Javascripit类型转换比较那点事儿,双等号(==)
  • laravel 用artisan创建自己的模板
  • mongo索引构建
  • oldjun 检测网站的经验
  • Redash本地开发环境搭建
  • Tornado学习笔记(1)
  • web标准化(下)
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 聊聊sentinel的DegradeSlot
  • 设计模式 开闭原则
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 延迟脚本的方式
  • 异常机制详解
  • 用element的upload组件实现多图片上传和压缩
  • 用Python写一份独特的元宵节祝福
  • linux 淘宝开源监控工具tsar
  • Spring第一个helloWorld
  • # include “ “ 和 # include < >两者的区别
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #### go map 底层结构 ####
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (2)Java 简介
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (LeetCode 49)Anagrams
  • (NSDate) 时间 (time )比较
  • (层次遍历)104. 二叉树的最大深度
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (附源码)计算机毕业设计ssm电影分享网站
  • (简单) HDU 2612 Find a way,BFS。
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .CSS-hover 的解释
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net core 连接数据库,通过数据库生成Modell