当前位置: 代码网 > it编程>数据库>MsSqlserver > 在Django中如何执行原生SQL查询详解

在Django中如何执行原生SQL查询详解

2025年10月21日 MsSqlserver 我要评论
在django中,执行原生sql查询1. 使用raw()方法raw() 方法允许你执行原生sql查询并返回模型实例:from myapp.models import person# 基本查询peopl

在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 connection

def 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 connection

def 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 connections

def 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 connection

def update_data():
    with connection.cursor() as cursor:
        # insert
        cursor.execute(
            "insert into myapp_person (name, age) values (%s, %s)",
            ['john', 30]
        )
        
        # update
        cursor.execute(
            "update myapp_person set age = %s where name = %s",
            [31, 'john']
        )
        
        # delete
        cursor.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 connection

def 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]
)

注意事项

  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,同时保持代码的安全性和可维护性。

总结

到此这篇关于在django中如何执行原生sql查询的文章就介绍到这了,更多相关django执行原生sql查询内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com