Django技术疑问:ORM连接管理与objects.raw()返回结果异常
Django新手技术问题解答
问题1:Postgres连接延迟与Django ORM的连接管理
我使用Postgres数据库,此前用psycopg2的connection/cursor获取数据时,建立连接存在延迟。了解到Django ORM会处理建立连接等底层操作,请问使用Django ORM是否能解决连接延迟问题?
1.1 使用raw()方法时,是否也能获得同样的底层操作管理支持?
解答:
- Django ORM默认会维护数据库连接池,自动处理连接的建立、复用和释放,避免每次查询都重新创建连接,这能直接解决手动用psycopg2时的连接延迟问题。连接池会保留活跃连接供后续请求复用,大幅降低连接开销。
- 使用
raw()方法时,同样享受Django的连接管理支持。raw()是基于Django的数据库连接框架执行的,底层连接的复用、管理逻辑和普通ORM查询完全一致,不会回到手动管理连接的状态。
问题2:objects.raw(sql)返回查询语句而非记录的问题
我定义的Student模型如下:
class Student(models.Model): firstname = models.CharField(max_length=100) surname = models.CharField(max_length=100) def __str__(self): return self.firstname
视图代码如下:
def studentList(request): #posts = Student.objects.all() --> 1. working as expected (fetching all records firstname) cursor = connection.cursor() sql = "select * from api_student" cursor.execute(sql) posts = cursor.fetchone() --> 2. returning entire record #posts = Student.objects.raw(sql) --> 3. RETURNING SQL QUERY NOT RECORD FROM TABLE ??? print(posts) return render(request, 'output.html', {'posts':posts})
三种测试方式的输出分别为:
<QuerySet [<Student: Anil>]>(正常获取所有记录的名字)('Anil', 'kumar')(返回完整记录)<RawQuerySet: select * from api_student>(此为问题所在,请问我遗漏了什么?)
解答:
问题出在RawQuerySet的惰性求值特性:
Student.objects.raw(sql)返回的是RawQuerySet对象,它和Django普通的QuerySet一样,不会立即执行SQL查询,只有当你主动遍历它、访问其中的元素,或者将其转换为列表时,才会实际执行SQL并返回对应的Student模型实例。- 直接打印
RawQuerySet只会显示查询的描述信息,不会触发数据获取。
解决方法:
在视图中主动触发查询:将
RawQuerySet转换为列表,强制执行查询:posts = list(Student.objects.raw(sql))此时打印
posts会得到类似[<Student: Anil>]的结果,和objects.all()的输出格式一致。在模板中直接遍历:如果是在模板中使用,无需额外处理,直接像遍历普通
QuerySet一样循环即可,模板会自动触发查询:{% for post in posts %} <p>{{ post.firstname }} - {{ post.surname }}</p> {% endfor %}
内容的提问来源于stack exchange,提问作者anilraj
相关产品推荐
相关产品推荐

