Django数据库操作(执行原生SQL的几种方法)

本文深入探讨了Django ORM的高级查询技巧,包括使用extra方法进行结果集修改,使用raw方法执行原始SQL并返回模型,以及如何通过游标执行自定义SQL。这些技巧能够帮助开发者更灵活地操作数据库。

1.使用extra方法

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

  说明:依赖model模型

  用在where后:

    Book.objects.filter(publisher_id="1").extra(where=["title='python学习1'"])    

  用在select后  

    Book.objects.filter(publisher_id="1").extra(select={"count":"select count(*) from hello_book"})

 

2.使用raw方法

  解释:执行原始sql并返回模型

  说明:依赖model多用于查询

  用法:

    book = Book.objects.raw("select * from hello_book")
    for item in book:
      print(item.title)

 

3.执行自定义SQL

  解释:利用游标执行

  导入:from django.db import connection

  说明:不依赖model

  用法:  

    from django.db import connection

    cursor = connection.cursor()
    #插入
    cursor.execute("insert into hello_author(name) values('xiaol')")
    #更新
    cursor.execute("update hello_author set name='xiaol' where id=1")
    #删除
    cursor.execute("delete from hello_author where name='xiaol'")
    #查询
    cursor.execute("select * from hello_author")
    #返回一行
    raw = cursor.fetchone()
    print(raw)
    # #返回所有
    # cursor.fetchall()

Django执行原生 SQL 查询以处理复杂查询场景,可以使用以下几种方式: ### 使用 `cursor` 执行自定义 SQL Django 提供了直接访问数据库的功能,可以通过 `connection` 和 `cursor` 对象来执行原生 SQL。这种方法适用于需要完全控制 SQL 语句的情况。 ```python from django.db import connection def execute_raw_sql(query, params=None): with connection.cursor() as cursor: cursor.execute(query, params or []) if query.lower().startswith('select'): rows = cursor.fetchall() return rows else: return None ``` - `cursor.execute()`:执行 SQL 语句。 - `cursor.fetchall()`:用于获取查询结果的行数据。 - `with connection.cursor()`:确保游标在使用后正确关闭。 ### 使用 `Manager.raw()` 方法 如果需要返回模型实例对象,可以使用 `Manager.raw()` 方法。它允许执行原始 SQL 并将结果映射到模型实例。 ```python query = 'SELECT * FROM myapp_mymodel WHERE some_column = %s' results = MyModel.objects.raw(query, [value]) ``` - `raw()` 方法支持参数化查询,防止 SQL 注入攻击。 - 返回的对象是模型实例,可以直接访问其属性[^2]。 ### 使用 `RunSQL` 在迁移中执行 SQL 如果希望在迁移中执行 SQL 脚本,可以使用 `RunSQL` 操作。这在需要修改数据库结构或填充数据时非常有用。 ```python from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('myapp', 'previous_migration'), ] operations = [ migrations.RunSQL( sql="CREATE INDEX my_index ON myapp_mymodel (some_column);", reverse_sql="DROP INDEX my_index;" ) ] ``` - `RunSQL` 可以直接嵌入到迁移文件中,确保数据库结构的同步。 - `reverse_sql` 参数用于回滚操作,提高迁移的安全性[^1]。 ### 使用 `extra()` 查询 `extra()` 是一种结果集修改器,允许添加额外的 SQL 片段到查询中。尽管它在某些情况下仍然有用,但 Django 官方推荐优先使用 `annotate()` 和 `F()` 等更现代的方法。 ```python queryset = MyModel.objects.extra( where=['some_column = %s'], params=[value] ) ``` - `extra()` 支持 `where`、`select`、`tables` 等参数,用于扩展查询条件。 - 不推荐在新代码中广泛使用 `extra()`,因为它的功能可以通过 ORM 的其他方法替代。 ### 注意事项 - **安全性**:在执行原始 SQL 时,务必使用参数化查询(如 `cursor.execute()` 的 `params` 参数),以防止 SQL 注入攻击。 - **性能**:直接执行 SQL 可能会绕过 ORM 的一些优化机制,因此需要仔细测试性能影响。 - **可移植性**:原始 SQL 通常与特定的数据库后端绑定,可能会降低代码的可移植性。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值