iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Django怎么使用原生SQL查询数据库
  • 682
分享到

Django怎么使用原生SQL查询数据库

2023-07-06 00:07:54 682人浏览 薄情痞子
摘要

这篇文章主要介绍“Django怎么使用原生sql查询数据库”,在日常操作中,相信很多人在DjanGo怎么使用原生SQL查询数据库问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Django怎么使用原生SQL查询

这篇文章主要介绍“Django怎么使用原生sql查询数据库”,在日常操作中,相信很多人在DjanGo怎么使用原生SQL查询数据库问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Django怎么使用原生SQL查询数据库”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Django 提供了两种方式来执行原生 SQL 代码。

一种是使用 raw() 函数,一种是 使用 connection.cursor()。

但是官方还是推荐在使用原生 SQL 之前,尽量的先去探索一下 QuerySet 提供的各种 api

目前而言,官方文档提供的各种 API 是能够满足绝大多数的应用场景的。

1、raw()

这个方法可以用来操作原生 SQL,然后返回 model 实例:

我们以 Blog 作为示例,使用的代码如下:

for blog in Blog.objects.raw("select * from blog_blog"):    print(blog)

上面这段代码的作用效果跟 Blog.objects.all() 获取的结果是一样的,但是在一些操作上又不太一样,比如 all().count() 可以获取到 总数,但是 raw() 就不能进行这种操作。

需要注意的是,raw() 并不会去检测输入的 SQL 代码,即使我们使用 Blog 这个model 来查询 Entry 的数据,也能够返回结果,不过返回的都是 Entry 表的属性:

for blog in Blog.objects.raw("select * from blog_entry"):    print(blog.__dict__)  # __dict__ 输出的都是 blog_entry 的字段

也就是说 在 Blog.objects.raw() 中,真正起作用的只有 raw() 这一个函数,前面的 Blog 不过是一个架子,或者途径,是为了引出 raw() 这个函数。

自定义返回字段

在 raw() 函数的 SQL 代码里,我们可以自定义选中的字段,如果需要使用没有选中的字段,那么系统会再次访问数据库来获取,这个操作过程就跟前面介绍的 defer() 函数一样。

for item in Blog.objects.raw("select id from blog_blog"):    print(item.__dict__)    print(item.id, item.name)    print(item.__dict__){'_state': <django.db.models.base.ModelState object at 0x7fbd4165b6a0>, 'id': 2}2 hunter{'_state': <django.db.models.base.ModelState object at 0x7fbd4165b6a0>, 'id': 2, 'name': 'hunter'}

可以看到,返回的结果中先输出的数据只有 id,后面,当我们访问 name 字段的时候,又去获取了 name 字段的数据。

自定义字段必须包含主键

当我们自定义字段返回的时候,必须是要包含主键字段的,否则在我们获取信息的时候会报错,比如下面的操作:

for blog in Blog.objects.raw("select name from blog_blog"):    print(blog.__dict__)

在 print(blog.dict) 的时候就会报错,数据中没有主键信息

自定义返回新字段

可以跟 QuerySet 的 annotate 操作一样,自定义新字段返回,获取的时候可以直接根据属性值返回,比如:

entry = Entry.objects.raw("select *, date_fORMat(pub_date, '%%Y-%%m') as date_1 from blog_entry")[0]print(entry.date_1)

传递变量

给输入的 SQL 语句传递变量:

name = "python"Blog.objects.raw("select * from blog_blog where name = '%s'", [name])

2、connection.cursor()

Django 推出了一种更加直接执行 SQL 的方式,用到的模块是 django.db.connction,用到的 cursor 和 pymysql 的库是一样的用法,官方给出的示例如下:

from django.db import connectiondef my_custom_sql(self):    with connection.cursor() as cursor:        cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])        row = cursor.fetchone()    return row

需要注意,如果有参数传入 SQL 中,需要对一些符号进行转义之后才可以使用,比如:

cursor.execute("SELECT foo FROM bar WHERE baz = '30%'")cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' AND id = %s", [self.id])

其中,第二条语句的 % 需要进行转义

适配fetch的数据

通过 fetchone 和 fetchall() 返回的数据是只有 value 值的,没有对应的字段 key,如果可以适当的牺牲性能和内存,来换取获取数据的便利和准确性,官方提供了这样一种方式:

def dictfetchall(cursor):    "Return all rows from a cursor as a dict"    columns = [col[0] for col in cursor.description]    return [        dict(zip(columns, row))        for row in cursor.fetchall()    ]

在我们执行完 cursor.execute(sql) 之后,把 cursor 作为参数传入 dictfetchall 函数中,就可以返回一个字典列表

介绍一下 cursor.description,这个返回的是一个元组数据,里面的元素也是一个元组,元组的第一个元素就是我们 select 的字段名。

所以 columns = [col[0] for col in cursor.description] 这一行代码获取的是指定的所有字段名

使用示例:

def dictfetchall(cursor):    "Return all rows from a cursor as a dict"    columns = [col[0] for col in cursor.description]    return [        dict(zip(columns, row))        for row in cursor.fetchall()    ]with connection.cursor() as cursor:sql = "select id, name from blog_blog"cursor.execute(sql)results = dictfetchall(cursor)print(results)# 返回的结果:# [{'id': 20, 'name': 'name_3'}, {'id': 21, 'name': 'name_4'}, {'id': 1, 'name': 'name_5'}]

在我使用的过程中,我们使用的是上下文管理器的方式来获取游标:

with connection.cursor() as cursor:cursor.execute()

所以,使用完之后,不需要手动关闭,他与下面的用法效果是一致的:

c = connection.cursor()try:    c.execute(...)finally:    c.close()

但推荐的还是上下文管理器的方式,更优雅。

3、多数据库操作

如果系统用到了多个数据库,那么在使用 cursor 的时候,就需要使用到 django.db.connections 模块:

from django.db import connectionswith connections['my_db_alias'].cursor() as cursor:    pass

到此,关于“Django怎么使用原生SQL查询数据库”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Django怎么使用原生SQL查询数据库

本文链接: https://www.lsjlt.com/news/356629.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 生态系统中流行库和框架的贡献指南
    作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
    99+
    2024-05-15
    框架 c++ 流行库 git
  • C++ 生态系统中流行库和框架的社区支持情况
    c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
    99+
    2024-05-15
    生态系统 社区支持 c++ overflow 标准库
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-15
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-15
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-15
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-15
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-15
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-15
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-15
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-15
    golang 数据库备份 mysql git 标准库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作