更新时间:2023-01-30 来源:黑马程序员 浏览量:
Django中允许开发人员使用两种方式执行原始SQL语句:一种使用模型管理器的raw()方法执行原始查询语句并返回模型实例;另一种完全不经过模型层,利用Django提供的默认数据库django.db.connection获取游标对象,再通过游标对象调用execute()方法直接执行SQL语句。
1.使用Manager.raw()方法执行SQL查询语句
Manager.raw()方法接收一个原始SQL查询语句,返回一个RawQuerySet对象,该对象是一个查询集,与QuerySet对象一样支持迭代操作。
raw()方法的语法格式如下:
Manager.raw(raw_query,params=None,translations=None)
raw()方法中各个参数的具体含义如下:
①raw_query:表示原始的SQL语句。
②params:查询条件参数,接收列表或字典类型的数据。
③translations:表示字段映射表,接收存储查询字段与模型字段映射关系的字典型数据。
使用raw()方法查询数据表person中所有的数据,代码如下:
person = Person.objects.raw("select * from person")
以上代码等价于“Person.objects.all()”。
raw()方法将查询语句中的字段映射至模型字段,因此raw()方法中字段的顺序并不影响查询出的结果。示例如下:
Person.objects.raw("select id,person_age,person_name from person") Person.objects.raw("select person_age,id,person_name from person")
以上示例代码的查询结果一致。
需要注意的是,Django中使用主键来区分模型实例,因此,raw()方法的原始SQL查询语句中必须包含主键,否则会抛出invalidQuery异常。
raw()方法根据字段名称查询数据,raw()方法中的SQL语句可以使用as关键字为字段设置别名。示例如下:
Person.objects.raw("select pk as id,p_age as person_age, p_name as person_name from person")
上述的语句表示在数据表中查询字段id、person_age、person_name。通过raw()方法的translatitons参数也可以实现此查询,示例如下:
query_map = {"pk:id","p_age:person_age","p_name:person_name"} Person.objects.raw("select * from person",translations=query_map)
raw()方法还支持索引,若只需要第一个查询结果,则可使用如下形式:
person = Person.objects.raw("select * from person")[0]
在查询数据时,可以使用raw()方法中参数params为原始SQL语句传递查询参数,该参数可以为一个列表或字典类型的数据。
将查询条件作为参数使用raw()方法进行查询,示例如下:
param = ['person_name'] p_name = Person.objects.raw("select id,%s from person",param)
上述语句表示查询数据表person中的id、person_name字段。
使用“%(key)s”作为占位符可以为raw()方法的参数params传递一个字典类型的参数,其中key由参数中的key替换。示例如下:
param = {"id"=1} P_name =Person.objects.raw("select * from person where id=%(id)s',param)
上述语句表示查询数据表person中id为1的记录。
需要说明的是,如果使用的是SQLite数据库,那么参数params只能以列表形式传入。
2.利用游标对象执行SQL语句
虽然使用raw()方法可以通过模型查询到数据表中的数据,但是在实际开发中还可能需要对未映射至模型的数据进行查询,或更新、插入、删除,此时无法再使用raw()方法,只能绕过模型直接访问数据库。
django.db.conneciton提供默认数据库连接,使用connection.cursor()方法可以获取数据库游标对象,使用游标对象的execute()方法可以执行原始的SQL语句。
例如,使用connection对象查询数据表person中所有数据,示例如下:
from django.db import connection conn = connection.cursor() conn.execute('select * from person')
fetchone()与fetchall()也是数据库游标对象的常用方法,它们分别返回查询集中的一条/全部记录。使用fetchone()查询一条记录,示例如下:
conn.fetchone()
以上示例代码将查询出一条记录。
使用fetchall()查询所有记录,示例如下:
conn.fetchall()
以上示例代码将查询出所有记录。