转:django 执行原始SQL查询 raw sql



摘自
The Django Book
第10章: 数据模型高级进阶
http://djangobook.py3k.cn/2.0/chapter10/


https://docs.djangoproject.com/en/dev/topics/db/sql/




django 执行原始SQL查询

有时候你会发现Django数据库API带给你的也只有这么多,那你可以为你的数据库写一些自定义SQL查询。 你可以通过导入django.db.connection对像来轻松实现,它代表当前数据库连接。 要使用它,需要通过connection.cursor()得到一个游标对像。 然后,使用cursor.execute(sql, [params])来执行SQL语句,使用cursor.fetchone()或者cursor.fetchall()来返回记录集。 例如:

>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute("""
...    SELECT DISTINCT first_name
...    FROM people_person
...    WHERE last_name = %s""", ['Lennon'])
>>> row = cursor.fetchone()
>>> print row
['John']

connection和cursor几乎实现了标准Python DB-API,你可以访问` http://www.python.org/peps/pep-0249.html <http://www.python.org/peps/pep-0249.html>`__来获取更多信息。 如果你对Python DB-API不熟悉,请注意在cursor.execute() 的SQL语句中使用`` “%s”`` ,而不要在SQL内直接添加参数。 如果你使用这项技术,数据库基础库将会自动添加引号,同时在必要的情况下转意你的参数。

不要把你的视图代码和django.db.connection语句混杂在一起,把它们放在自定义模型或者自定义manager方法中是个不错的主意。 比如,上面的例子可以被整合成一个自定义manager方法,就像这样:

from django.db import connection, models

class PersonManager(models.Manager):
    def first_names(self, last_name):
        cursor = connection.cursor()
        cursor.execute("""
            SELECT DISTINCT first_name
            FROM people_person
            WHERE last_name = %s""", [last_name])
        return [row[0] for row in cursor.fetchone()]

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    objects = PersonManager()

然后这样使用:

>>> Person.objects.first_names('Lennon')
['John', 'Cynthia']
===================================================

https://docs.djangoproject.com/en/dev/topics/db/sql/

 

Performing raw SQL queries

When the model query APIs don’t go far enough, you can fall back to writing raw SQL. Django gives you two ways of performing raw SQL queries: you can use Manager.raw() to perform raw queries and return model instances, or you can avoid the model layer entirely and execute custom SQL directly.

转载于:https://www.cnblogs.com/4admin2root/articles/2752421.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用Django的`raw()`方法执行原始SQL查询并对结果进行遍历时,可能会遇到性能较慢的问题。这可能是因为`raw()`方法返回的是一个懒惰的查询集,它会在每次访问结果时都执行一次数据库查询,导致性能下降。 为了提高性能,你可以尝试以下方法: 1. 批量获取结果:尝试一次性获取所有结果,而不是逐个获取。你可以使用`list()`方法将查询集换为列表,并将其缓存在内存中,然后对列表进行迭代。这样可以减少对数据库的查询次数。 ```python query = "SELECT * FROM your_table" results = YourModel.objects.raw(query) results_list = list(results) # 将查询集换为列表 for result in results_list: # 迭代处理结果 # ... ``` 2. 使用`iterator()`方法:`iterator()`方法返回一个生成器,可以逐个从数据库中获取结果。这样可以减少内存使用,并提高性能。 ```python query = "SELECT * FROM your_table" results = YourModel.objects.raw(query) for result in results.iterator(): # 迭代处理结果 # ... ``` 3. 使用`prefetch_related()`方法:如果你在查询中涉及到外键关系,可以使用`prefetch_related()`方法来预加载相关对象,以减少额外的数据库查询。 ```python query = "SELECT * FROM your_table" results = YourModel.objects.raw(query).prefetch_related('related_model') for result in results: # 迭代处理结果及其相关对象 # ... ``` 尝试上述方法中的任何一种都可能改善查询结果遍历的性能。根据你的具体情况选择合适的方法。如果问题仍然存在,请提供更多相关代码和数据库结构的信息,以便更好地帮助你解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值