Django视图中的原始SQL查询

Dav*_*542 27 django django-models django-queryset django-views

如何在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))
Run Code Online (Sandbox Code Playgroud)

这个结果函数会是什么样的?谢谢.

DTi*_*ing 49

>>> 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
Run Code Online (Sandbox Code Playgroud)

使用WHERE子句筛选yes的投票:

>>> cursor.execute('''SELECT count(*) FROM people_person WHERE vote = "yes"''')
1L
Run Code Online (Sandbox Code Playgroud)

  • 很有用!谢谢!我使用了 `rows = cursor.fetchall()`。 (5认同)

zee*_*kay 44

Django文档非常好.您基本上有两个选项来执行原始SQL.您可以使用它Manager.raw()来执行返回模型实例的原始查询,也可以避免使用模型层并直接执行自定义SQL.

使用raw()经理:

>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
...     print p
John Smith
Jane Jones
Run Code Online (Sandbox Code Playgroud)

如果要直接绕过模型层,可以使用django.db.connectionwhich表示默认的数据库连接:

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
Run Code Online (Sandbox Code Playgroud)

  • 不,它返回一个`RawQuerySet`,它只在你想要返回一个模型实例时才有用.要执行`count(*)`或其他任何你不想返回模型实例的东西,你最好只使用`django.db.connection`. (2认同)

Adi*_*tya 12

如果您使用 PostgreSQL,则可以在一个查询内完成此操作。如果没有,您可以相应地更改查询并获取结果。

from django.db import connection

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
Run Code Online (Sandbox Code Playgroud)


san*_*_dj 9

具有特定数据库名称的原始sql:

from django.db import connections
cursor = connections['default'].cursor()
cursor.execute("select * from table_name")
print(cursor.fetchall())

# manually close the cursor if you are done!
cursor.close()
Run Code Online (Sandbox Code Playgroud)
database_name = Any database created by us
table_name = Any table name created by us
Run Code Online (Sandbox Code Playgroud)


Tin*_*ert 6

你可以试试这个

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 ")
Run Code Online (Sandbox Code Playgroud)