Django 中的 connection.cursor() 执行 SQL 用法

        在 Django 开发中,通常依赖于 Django ORM 来处理数据库操作,它提供了一个高级的抽象层,使得数据库交互更加直观和安全。然而,有时可能需执行一些复杂的查询或数据库操作,这些操作可能超出了 ORM 的能力范围(比如动态生成DB表结构等等)。在这些情况下,可以使用 Django 的底层数据库 API 来执行原生 SQL 语句。本文将介绍如何在 Django 中使用 connection.cursor() 来执行 SQL 语句。


Django 的数据库连接

获取游标

要执行SQL查询,首先需要获取数据库的游标:

from django.db import connection

cursor = connection.cursor()

执行查询

有了游标,才可执行SQL查询:

cursor.execute("SELECT * FROM my_table")

处理结果

执行查询后,你可以使用 fetchone()fetchmany() 或 fetchall() 方法来检索结果:

rows = cursor.fetchall()  # 读取所有数据,下面有介绍其他方法
for row in rows:
    print(row)
    print(row[0])

关闭游标

完成数据库操作后,应关闭游标以释放资源:

cursor.close()

使用上下文管理器(推荐)

为简化资源管理,推荐使用 with 语句作为上下文管理器,会在代码块执行完毕后自动关闭游标:

with connection.cursor() as cursor:
    cursor.execute("SELECT * FROM my_table")

 

        更多connection.cursor() 执行 SQL 用法

执行 SQL 查询

有了游标对象,可用它来执行 SQL 查询。以下是一个执行 SELECT 查询的例子:

cursor.execute("SELECT * FROM myapp_mymodel")

你也可以使用参数化查询来防止 SQL 注入攻击:

cursor.execute("SELECT * FROM myapp_mymodel WHERE id = %s", [some_id])

获取查询结果

执行查询后,你可以使用游标的 fetchone()fetchmany() 或 fetchall() 方法来检索结果。

# 获取单个结果
row = cursor.fetchone()

# 获取多个结果(可以指定数量)
rows = cursor.fetchmany(size=5)

# 获取所有结果
rows = cursor.fetchall()

一些读取操作:

# 读取
for tup in cursor.fetchall():
    data.append({"id": tup[0], "name": tup[1], "teach_id": tup[2], "teacher_name": tup[3], "content": tup[4]})

# 判断
one = cursor.fetchone()
if one is not None:
    return Response({'message': f'{one[0]}已存在'}, status=status.HTTP_400_BAD_REQUEST)

但有发现,返回的都是一个列表,而无法直接用数据库表字段名锁定,这是有个其他方法,能锁定到字段名对应的索引列。

columns = {col[0]: idx for idx, col in enumerate(cursor.description)}

print(columns)
# {'create_time': 0, 'update_time': 1, 'uid': 2, 'task_uid': 3, 'usage': 4, 'type': 5}
# k-v 为 字段名-索引



# 获取所有行
rows = cursor.fetchall()
for row in rows:
    # 使用列名来访问数据
    name = row[columns['name']]
    print(name)

执行事务

在执行更新、删除或插入操作时,你可能需要使用事务来确保数据的一致性。Django 默认在每个请求的末尾自动提交事务,但你可以手动控制事务的提交和回滚(在执行 INSERT、UPDATE 或 DELETE 操作时,大可能控制事务的提交和回滚):

try:
    with connection.cursor() as cursor:
        # 执行SQL查询
        cursor.execute("UPDATE my_table SET field = %s WHERE another_field = %s", ['new_value', 'some_value'])
        # 提交更改
        connection.commit()  

except Exception as err:
    # 发生异常,回滚事务
    connection.rollback()
    print("An error occurred: ", err)

注:

  • 用 SQL 查询可能会绕过 Django 的安全和验证机制,因此需要谨慎处理输入。
  • 原生 SQL 查询时,确保查询与你的数据库后端兼容。
  • 用 connection.cursor() 时,记得遵循数据库的最佳实践,比如使用参数化查询来防止 SQL 注入。

相关推荐

  1. Django connection.cursor() 执行 SQL

    2024-02-02 08:58:01       39 阅读
  2. SQLLIMIT简单

    2024-02-02 08:58:01       50 阅读
  3. SQLWITH RECURSIVE

    2024-02-02 08:58:01       39 阅读
  4. SQLPIVOT函数

    2024-02-02 08:58:01       94 阅读
  5. SQLdistinct

    2024-02-02 08:58:01       30 阅读
  6. [hive] sqldistinct和注意事项

    2024-02-02 08:58:01       64 阅读
  7. SQLLAG函数与LEAD函数

    2024-02-02 08:58:01       32 阅读
  8. EXISTS在SQL

    2024-02-02 08:58:01       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-02 08:58:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-02 08:58:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-02 08:58:01       87 阅读
  4. Python语言-面向对象

    2024-02-02 08:58:01       96 阅读

热门阅读

  1. git 删除gitlab上指定的文件夹或者文件

    2024-02-02 08:58:01       46 阅读
  2. [Git版本控制系统]

    2024-02-02 08:58:01       51 阅读
  3. Oracle Months_between 用法

    2024-02-02 08:58:01       54 阅读
  4. IP 了解

    IP 了解

    2024-02-02 08:58:01      52 阅读
  5. C# 求幂算法,最大公约数,最小公倍数

    2024-02-02 08:58:01       49 阅读
  6. js寄⽣组合继承和优缺点

    2024-02-02 08:58:01       49 阅读
  7. Node.js EventEmitter详解

    2024-02-02 08:58:01       57 阅读
  8. spring boot bean的生命周期

    2024-02-02 08:58:01       40 阅读
  9. Flask 入门5 :过滤器

    2024-02-02 08:58:01       60 阅读
  10. docker-compose安装配置jenkins

    2024-02-02 08:58:01       45 阅读
  11. opencv——照片裁剪/照片斜的摆正

    2024-02-02 08:58:01       53 阅读