Python Django 之 直接执行自定义SQL语句
Posted xibuhaohao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python Django 之 直接执行自定义SQL语句相关的知识,希望对你有一定的参考价值。
一、执行自定义SQL方法
1、Executing custom SQL directly
直接执行自定义SQL,这种方式可以完全避免数据模型,而是直接执行原始的SQL语句。
2、Manager.raw()
执行原始查询并返回模型实例
二、Executing custom SQL directly
Manager.raw() 远远不够,可直接执行自定义SQL,directly execute UPDATE , INSERT , or DELETE queries.django.db.connection:代表默认的数据库连接
django.db.transaction :代表默认数据库事务(transaction)
用database connection调用 connection.cursor() 得到一个游标(cursor)对象。
然后调用 cursor.execute(sql, [params]) 执行SQL
cursor.fetchone() 或者 cursor.fetchall(): 返回结果行
如果执行修改操作,则调用 transaction.commit_unless_managed()来保证你的更改提交到数据库。
def my_custom_sql():
from django.db import connection, transaction
cursor = connection.cursor()
# 数据修改操作——提交要求
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
transaction.commit_unless_managed()
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
transaction.commit_unless_managed()
# 数据检索操作,不需要提交
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
django.db.connections :针对使用多个数据库
from django.db import connections
cursor = connections[\'my_db_alias\'].cursor()
# Your code here...
transaction.commit_unless_managed(using=\'my_db_alias\')
通常我们不需要手动调用 transaction.commit_unless_managed( ),我们可以这样做:
@commit_on_success
def my_custom_sql_view(request, value):
from django.db import connection, transaction
cursor = connection.cursor()
django.db.connections :针对使用多个数据库
from django.db import connections
cursor = connections[\'my_db_alias\'].cursor()
# Your code here...
transaction.commit_unless_managed(using=\'my_db_alias\')
通常我们不需要手动调用 transaction.commit_unless_managed( ),我们可以这样做:
@commit_on_success
def my_custom_sql_view(request, value):
from django.db import connection, transaction
cursor = connection.cursor()
# Data modifying operation
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value])
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value])
# Since we modified data, mark the transaction as dirty
transaction.set_dirty()
transaction.set_dirty()
# Data retrieval operation. This doesn\'t dirty the transaction,
# so no call to set_dirty() is required.
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value])
row = cursor.fetchone()
# so no call to set_dirty() is required.
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value])
row = cursor.fetchone()
return render_to_response(\'template.html\', {\'row\': row})
查看Django ORM执行的SQL语句 : connection.queries
查看Django ORM执行的SQL语句 : connection.queries
三、raw()方法
1、raw()用法
The raw() manager method can be used to perform raw SQL queries that return model instances:
Manager. raw ( raw_query , params=None , translations=None )
用法:
>>> for p in Person.objects.raw(\'SELECT * FROM Person LIMIT 2\'):
... print p
John Smith
Jane Jones
注意,原始SQL里的model,如果在 db_table 没有定义,则使用app的名称,后面下划线 后面接模型类的名称,如"Myblog_New";上面的例子,在定义类的时候已经这样处理了:
Class New(models.Model):
......
......
#自定义表名
class Meta:
db_table = \'New\'
Manager. raw ( raw_query , params=None , translations=None )
用法:
>>> for p in Person.objects.raw(\'SELECT * FROM Person LIMIT 2\'):
... print p
John Smith
Jane Jones
注意,原始SQL里的model,如果在 db_table 没有定义,则使用app的名称,后面下划线 后面接模型类的名称,如"Myblog_New";上面的例子,在定义类的时候已经这样处理了:
Class New(models.Model):
......
......
#自定义表名
class Meta:
db_table = \'New\'
2、查询字段隐射到模型字段(Mapping query fields to model fields)
raw() automatically maps fields in the query to fields on the model.并且是通过名称来匹配,这意味着我们可以使用SQL子句(clause)
>>> Person.objects.raw(\'\'\'SELECT first AS first_name,
... last AS last_name,
... bd AS birth_date,
... pk as id,
... FROM some_other_table\'\'\')
返回一个RawQuerySet对象
>>> Person.objects.raw(\'\'\'SELECT first AS first_name,
... last AS last_name,
... bd AS birth_date,
... pk as id,
... FROM some_other_table\'\'\')
返回一个RawQuerySet对象
3、索引查找(Index lookups)
first_person = Person.objects.raw(\'SELECT * from myapp_person\')[0]
first_person = Person.objects.raw(\'SELECT * from myapp_person LIMIT 1\')[0]
#然而,索引和切片不是在数据库级别上执行(除LIMIT外)
first_person = Person.objects.raw(\'SELECT * from myapp_person LIMIT 1\')[0]
#然而,索引和切片不是在数据库级别上执行(除LIMIT外)
4、延迟模型字段(Deferring model fields)
Fields may also be left out(left out:忽视,不考虑;被遗忘),这意味着该字段的查询将会被排除在根据需要时的加载。
>>> for p in Person.objects.raw(\'SELECT id, first_name FROM myapp_person\'):
... print p.first_name, # 这将检索到原始查询
... print p.last_name # 这将检索需求
...
John Smith
Jane Jones
这个例子其实检索了三个字段,一个主键(必需)、一个原始SQL字段、一个需求字段。这里主键字段不能省略,否则会出错,如下:
>>> for p in Person.objects.raw(\'SELECT id, first_name FROM myapp_person\'):
... print p.first_name, # 这将检索到原始查询
... print p.last_name # 这将检索需求
...
John Smith
Jane Jones
这个例子其实检索了三个字段,一个主键(必需)、一个原始SQL字段、一个需求字段。这里主键字段不能省略,否则会出错,如下:
5、传递参数(Passing parameters into raw() )
如果需要执行参数化查询,您可以使用params参数原始()
注意两点:
注意两点:
(1)、必须使用[参数],否则出错:
(2)、这种方式不对:
Error:
>>> query = \'SELECT * FROM myapp_person WHERE last_name = %s\' % lname
>>> Person.objects.raw(query)
(2)、这种方式不对:
Error:
>>> query = \'SELECT * FROM myapp_person WHERE last_name = %s\' % lname
>>> Person.objects.raw(query)
转载自:https://www.cnblogs.com/hello-/articles/9095444.html
以上是关于Python Django 之 直接执行自定义SQL语句的主要内容,如果未能解决你的问题,请参考以下文章