Django 视图中的原始 SQL 查询
Posted
技术标签:
【中文标题】Django 视图中的原始 SQL 查询【英文标题】:Raw SQL queries in Django views 【发布时间】:2011-08-21 08:31:36 【问题描述】:如何在views.py
中使用原始 SQL 执行以下操作?
from app.models import Picture
def results(request):
all = Picture.objects.all()
yes = Picture.objects.filter(vote='yes').count()
return render_to_response('results.html', 'picture':picture, 'all':all, 'yes': yes, context_instance=RequestContext(request))
results
函数会是什么样子?
【问题讨论】:
为什么要使用原始 sql 来进行过滤和计数? 这种情况没有实际原因。只是为了看看/知道怎么做。 【参考方案1】:>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute('''SELECT count(*) FROM people_person''')
1L
>>> row = cursor.fetchone()
>>> print row
(12L,)
>>> Person.objects.all().count()
12
使用 WHERE 子句过滤赞成票:
>>> cursor.execute('''SELECT count(*) FROM people_person WHERE vote = "yes"''')
1L
【讨论】:
非常有用!谢谢!我用rows = cursor.fetchall()
。【参考方案2】:
The Django Documentation is really really good. 执行原始 SQL 基本上有两种选择。您可以使用Manager.raw()
执行返回模型实例的原始查询,也可以避开模型层直接执行自定义SQL。
使用raw()
管理器:
>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
... print p
John Smith
Jane Jones
如果要直接绕过模型层,可以使用django.db.connection
,代表默认数据库连接:
def my_custom_sql():
from django.db import connection, transaction
cursor = connection.cursor()
# Data modifying operation - commit required
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
transaction.commit_unless_managed()
# Data retrieval operation - no commit required
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
【讨论】:
+1 很好的解释,你能用 raw 返回一个计数吗? 不,它返回一个RawQuerySet
,只有在你想返回一个模型实例时才有用。要执行count(*)
或您不想返回模型实例的任何其他操作,最好使用django.db.connection
。【参考方案3】:
如果您使用的是 PostgreSQL,则可以在一个查询中完成。 如果没有,您可以相应地更改查询并获取结果。
from django.db import connection
from app.models import Picture
def results(request):
with connection.cursor() as cursor:
query = """
SELECT count(*) as all_count,
count(*) FILTER(WHERE vote = 'yes') as yes_count
FROM people_person;
"""
cursor.execute(query)
row = cursor.fetchone()
all_count, yes_count = row
【讨论】:
【参考方案4】:你可以试试这个
Picture.objects.raw("SELECT 1 as id ,"\
"(SELECT count(*) as yes FROM people_person WHERE vote='yes') as yes ,"\
"(SELECT count(*) FROM people_person WHERE vote='no') as no ,"\
"(SELECT count(*) FROM people_person WHERE vote='all') as all ")
【讨论】:
这是一个脆弱的技巧,因为它只适用于整数主键(例如不是 uuid) 当我使用这种方式运行原始 SQL 时,我得到 NameError: name 'MyModel' is not defined。在 django ORM 的上下文下如何运行?【参考方案5】:具有特定数据库名称的原始 sql:
from django.db import connections
cursor = connections['database_name'].cursor()
cursor.execute("select * from table_name")
database_name = 我们创建的任何数据库
table_name = 我们创建的任何表名
【讨论】:
【参考方案6】:raw() 方法可用于执行返回模型实例的原始 sql 查询 ..see docs
books = Book.objects.raw('SELECT id,name,pages FROM app_books WHERE pages>100')
如果您执行的查询不能完全映射到模型.. django.db.connection 代表默认数据库连接,所以调用 connection.cursor() 使用数据库连接。 see docs
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
【讨论】:
以上是关于Django 视图中的原始 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章