更新時(shí)間:2023-01-30 來源:黑馬程序員 瀏覽量:
Django中允許開發(fā)人員使用兩種方式執(zhí)行原始SQL語句:一種使用模型管理器的raw()方法執(zhí)行原始查詢語句并返回模型實(shí)例;另一種完全不經(jīng)過模型層,利用Django提供的默認(rèn)數(shù)據(jù)庫(kù)django.db.connection獲取游標(biāo)對(duì)象,再通過游標(biāo)對(duì)象調(diào)用execute()方法直接執(zhí)行SQL語句。
1.使用Manager.raw()方法執(zhí)行SQL查詢語句
Manager.raw()方法接收一個(gè)原始SQL查詢語句,返回一個(gè)RawQuerySet對(duì)象,該對(duì)象是一個(gè)查詢集,與QuerySet對(duì)象一樣支持迭代操作。
raw()方法的語法格式如下:
Manager.raw(raw_query,params=None,translations=None)
raw()方法中各個(gè)參數(shù)的具體含義如下:
?、賠aw_query:表示原始的SQL語句。
?、趐arams:查詢條件參數(shù),接收列表或字典類型的數(shù)據(jù)。
③translations:表示字段映射表,接收存儲(chǔ)查詢字段與模型字段映射關(guān)系的字典型數(shù)據(jù)。
使用raw()方法查詢數(shù)據(jù)表person中所有的數(shù)據(jù),代碼如下:
person = Person.objects.raw("select * from person")
以上代碼等價(jià)于“Person.objects.all()”。
raw()方法將查詢語句中的字段映射至模型字段,因此raw()方法中字段的順序并不影響查詢出的結(jié)果。示例如下:
Person.objects.raw("select id,person_age,person_name from person") Person.objects.raw("select person_age,id,person_name from person")
以上示例代碼的查詢結(jié)果一致。
需要注意的是,Django中使用主鍵來區(qū)分模型實(shí)例,因此,raw()方法的原始SQL查詢語句中必須包含主鍵,否則會(huì)拋出invalidQuery異常。
raw()方法根據(jù)字段名稱查詢數(shù)據(jù),raw()方法中的SQL語句可以使用as關(guān)鍵字為字段設(shè)置別名。示例如下:
Person.objects.raw("select pk as id,p_age as person_age, p_name as person_name from person")
上述的語句表示在數(shù)據(jù)表中查詢字段id、person_age、person_name。通過raw()方法的translatitons參數(shù)也可以實(shí)現(xiàn)此查詢,示例如下:
query_map = {"pk:id","p_age:person_age","p_name:person_name"} Person.objects.raw("select * from person",translations=query_map)
raw()方法還支持索引,若只需要第一個(gè)查詢結(jié)果,則可使用如下形式:
person = Person.objects.raw("select * from person")[0]
在查詢數(shù)據(jù)時(shí),可以使用raw()方法中參數(shù)params為原始SQL語句傳遞查詢參數(shù),該參數(shù)可以為一個(gè)列表或字典類型的數(shù)據(jù)。
將查詢條件作為參數(shù)使用raw()方法進(jìn)行查詢,示例如下:
param = ['person_name'] p_name = Person.objects.raw("select id,%s from person",param)
上述語句表示查詢數(shù)據(jù)表person中的id、person_name字段。
使用“%(key)s”作為占位符可以為raw()方法的參數(shù)params傳遞一個(gè)字典類型的參數(shù),其中key由參數(shù)中的key替換。示例如下:
param = {"id"=1} P_name =Person.objects.raw("select * from person where id=%(id)s',param)
上述語句表示查詢數(shù)據(jù)表person中id為1的記錄。
需要說明的是,如果使用的是SQLite數(shù)據(jù)庫(kù),那么參數(shù)params只能以列表形式傳入。
2.利用游標(biāo)對(duì)象執(zhí)行SQL語句
雖然使用raw()方法可以通過模型查詢到數(shù)據(jù)表中的數(shù)據(jù),但是在實(shí)際開發(fā)中還可能需要對(duì)未映射至模型的數(shù)據(jù)進(jìn)行查詢,或更新、插入、刪除,此時(shí)無法再使用raw()方法,只能繞過模型直接訪問數(shù)據(jù)庫(kù)。
django.db.conneciton提供默認(rèn)數(shù)據(jù)庫(kù)連接,使用connection.cursor()方法可以獲取數(shù)據(jù)庫(kù)游標(biāo)對(duì)象,使用游標(biāo)對(duì)象的execute()方法可以執(zhí)行原始的SQL語句。
例如,使用connection對(duì)象查詢數(shù)據(jù)表person中所有數(shù)據(jù),示例如下:
from django.db import connection conn = connection.cursor() conn.execute('select * from person')
fetchone()與fetchall()也是數(shù)據(jù)庫(kù)游標(biāo)對(duì)象的常用方法,它們分別返回查詢集中的一條/全部記錄。使用fetchone()查詢一條記錄,示例如下:
conn.fetchone()
以上示例代碼將查詢出一條記錄。
使用fetchall()查詢所有記錄,示例如下:
conn.fetchall()
以上示例代碼將查詢出所有記錄。