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

【python】在Django中,执行原生SQL查询

文章目录

  • 在Django中,执行原生SQL查询
    • 1. 使用 `raw()` 方法
    • 2. 使用数据库连接直接执行SQL
      • 基本用法:
      • 返回字典格式的结果:
    • 3. 使用多个数据库
    • 4. 执行写操作(INSERT/UPDATE/DELETE)
    • 5. 事务处理
    • 6. 实用的封装函数
    • 注意事项

在Django中,执行原生SQL查询

1. 使用 raw() 方法

raw() 方法允许你执行原生SQL查询并返回模型实例:

from myapp.models import Person# 基本查询
people = Person.objects.raw('SELECT * FROM myapp_person WHERE age > %s', [18])# 遍历结果
for person in people:print(person.name, person.age)# 带参数的查询
people = Person.objects.raw('SELECT * FROM myapp_person WHERE age BETWEEN %s AND %s',[20, 30]
)

2. 使用数据库连接直接执行SQL

基本用法:

from django.db import connectiondef my_custom_sql():with connection.cursor() as cursor:# 执行查询cursor.execute("SELECT * FROM myapp_person WHERE age > %s", [25])# 获取所有结果rows = cursor.fetchall()# 或者逐行获取# row = cursor.fetchone()# rows = cursor.fetchmany(size=10)return rows

返回字典格式的结果:

from django.db import connectiondef dictfetchall(cursor):"""将游标结果转换为字典列表"""columns = [col[0] for col in cursor.description]return [dict(zip(columns, row))for row in cursor.fetchall()]def my_custom_sql():with connection.cursor() as cursor:cursor.execute("SELECT id, name, age FROM myapp_person")results = dictfetchall(cursor)return results

3. 使用多个数据库

如果你的项目配置了多个数据库:

from django.db import connectionsdef query_multiple_dbs():# 使用默认数据库with connections['default'].cursor() as cursor:cursor.execute("SELECT * FROM table1")# 处理结果# 使用其他数据库with connections['other_db'].cursor() as cursor:cursor.execute("SELECT * FROM table2")# 处理结果

4. 执行写操作(INSERT/UPDATE/DELETE)

from django.db import connectiondef update_data():with connection.cursor() as cursor:# INSERTcursor.execute("INSERT INTO myapp_person (name, age) VALUES (%s, %s)",['John', 30])# UPDATEcursor.execute("UPDATE myapp_person SET age = %s WHERE name = %s",[31, 'John'])# DELETEcursor.execute("DELETE FROM myapp_person WHERE age < %s",[18])

5. 事务处理

from django.db import transaction, connection@transaction.atomic
def complex_operation():with connection.cursor() as cursor:try:# 一系列SQL操作cursor.execute("UPDATE accounts SET balance = balance - %s", [100])cursor.execute("UPDATE accounts SET balance = balance + %s", [100])except Exception as e:# 出错时会自动回滚print(f"Error: {e}")

6. 实用的封装函数

from django.db import connectiondef execute_query(query, params=None, return_dict=True):"""执行SQL查询的通用函数"""with connection.cursor() as cursor:cursor.execute(query, params or [])if query.strip().upper().startswith('SELECT'):if return_dict:columns = [col[0] for col in cursor.description]return [dict(zip(columns, row)) for row in cursor.fetchall()]else:return cursor.fetchall()else:# 对于非SELECT查询,返回受影响的行数return cursor.rowcount# 使用示例
results = execute_query("SELECT name, age FROM myapp_person WHERE age > %s",[25]
)
Django原生SQL查询
raw方法
直接数据库连接
返回模型实例
支持模型方法
自动字段映射
connection.cursor
返回原始数据
手动结果处理
执行查询
SELECT查询
写操作
fetchall
fetchone
fetchmany
INSERT
UPDATE
DELETE
元组格式
字典格式转换

注意事项

  1. SQL注入防护:始终使用参数化查询,不要直接拼接字符串

    # ✅ 安全:使用参数化查询
    cursor.execute("SELECT * FROM users WHERE username = %s", [username])# ❌ 危险:字符串拼接(SQL注入风险)
    cursor.execute(f"SELECT * FROM users WHERE username = '{username}'")# ❌ 危险:直接传递用户输入
    cursor.execute("SELECT * FROM users WHERE username = %s" % username)
    
  2. 表名引用:在SQL中使用实际的数据库表名,而不是模型名

  3. 性能考虑:原生SQL通常更快,但失去了Django ORM的一些便利功能;使用直接连接:需要最高性能、复杂查询或跨表查询

  4. 数据库兼容性:如果你使用多个数据库后端,要注意SQL语法的差异

这些方法让你在需要优化性能或执行复杂查询时,能够灵活地使用原生SQL,同时保持代码的安全性和可维护性。

http://www.dtcms.com/a/507786.html

相关文章:

  • 5 个 Windows 故障排除工具
  • 云南网站建设招商交换友情链接的渠道
  • 在SCNet使用异构海光DCU 部署文心21B大模型报错HIP out of memory(未调通)
  • 嘉兴网站建设优化温州快速建站公司
  • 西安自助建站公司网站没有做404页面
  • 解决Vcenter告警datastore存储容量不足问题
  • 骆驼重链抗体免疫文库构建:从动物免疫到文库质控的关键技术解析
  • BearPi小熊派 鸿蒙开发入门笔记(1)
  • 湖州品牌网站设计wordpress侧栏导航栏
  • 使用EasyExcel生成下拉列表
  • 解密面向对象三大特征:封装、继承、多态
  • 未来之窗昭和仙君(二十六)复制指定元素内容到剪贴板——东方仙盟筑基期
  • nginx压缩包在windows下如何启动和停止使用nginx
  • 桐城住房和城乡建设局网站汶上网站建设多少钱
  • 一个外贸网站要多大的空间比较好帝国cms 网站地图插件
  • 国产DSP芯片FT6678的UART接口详解C++软件开发,嵌入式软件开发,Linux
  • 第十二周 waf绕过和前端加密绕过
  • 时间服务器练习
  • access数据库做网站互联网舆情忻州
  • php企业网站模板下载有没有做外贸免费网站
  • 关于Windows中PyExecjs库中文乱码的解决
  • 算法16.0
  • 卡码网语言基础课(Python) | 16.出现频率最高的字母
  • [优选算法专题四.前缀和——NO.28 除自身以外数组的乘积]
  • 垂直门户网站怎么做如何开设一个网站
  • 第一章 FreeRTOS简介
  • 【任务调度】DolphinScheduler钉钉告警消息格式修改
  • 医院的网站关键词定位一般是什么潜江招聘资讯网
  • 网站制作软件培训网络推广培训心得
  • YOLOv4:目标检测更亲民更精准