全國(guó)咨詢(xún)/投訴熱線:400-618-4000

首頁(yè)常見(jiàn)問(wèn)題正文

Django中執(zhí)行原始SQL語(yǔ)句有幾種方式?

更新時(shí)間:2023-01-30 來(lái)源:黑馬程序員 瀏覽量:

IT培訓(xùn)班

  Django中允許開(kāi)發(fā)人員使用兩種方式執(zhí)行原始SQL語(yǔ)句:一種使用模型管理器的raw()方法執(zhí)行原始查詢(xún)語(yǔ)句并返回模型實(shí)例;另一種完全不經(jīng)過(guò)模型層,利用Django提供的默認(rèn)數(shù)據(jù)庫(kù)django.db.connection獲取游標(biāo)對(duì)象,再通過(guò)游標(biāo)對(duì)象調(diào)用execute()方法直接執(zhí)行SQL語(yǔ)句。

  1.使用Manager.raw()方法執(zhí)行SQL查詢(xún)語(yǔ)句

  Manager.raw()方法接收一個(gè)原始SQL查詢(xún)語(yǔ)句,返回一個(gè)RawQuerySet對(duì)象,該對(duì)象是一個(gè)查詢(xún)集,與QuerySet對(duì)象一樣支持迭代操作。

  raw()方法的語(yǔ)法格式如下:

Manager.raw(raw_query,params=None,translations=None)

  raw()方法中各個(gè)參數(shù)的具體含義如下:

 ?、賠aw_query:表示原始的SQL語(yǔ)句。

 ?、趐arams:查詢(xún)條件參數(shù),接收列表或字典類(lèi)型的數(shù)據(jù)。

  ③translations:表示字段映射表,接收存儲(chǔ)查詢(xún)字段與模型字段映射關(guān)系的字典型數(shù)據(jù)。

  使用raw()方法查詢(xún)數(shù)據(jù)表person中所有的數(shù)據(jù),代碼如下:

person = Person.objects.raw("select * from person")

  以上代碼等價(jià)于“Person.objects.all()”。

  raw()方法將查詢(xún)語(yǔ)句中的字段映射至模型字段,因此raw()方法中字段的順序并不影響查詢(xún)出的結(jié)果。示例如下:

  Person.objects.raw("select id,person_age,person_name from person")
  Person.objects.raw("select person_age,id,person_name from person")

  以上示例代碼的查詢(xún)結(jié)果一致。

  需要注意的是,Django中使用主鍵來(lái)區(qū)分模型實(shí)例,因此,raw()方法的原始SQL查詢(xún)語(yǔ)句中必須包含主鍵,否則會(huì)拋出invalidQuery異常。

  raw()方法根據(jù)字段名稱(chēng)查詢(xún)數(shù)據(jù),raw()方法中的SQL語(yǔ)句可以使用as關(guān)鍵字為字段設(shè)置別名。示例如下:

   Person.objects.raw("select pk as id,p_age as person_age,
                                           p_name as person_name from person")

  上述的語(yǔ)句表示在數(shù)據(jù)表中查詢(xún)字段id、person_age、person_name。通過(guò)raw()方法的translatitons參數(shù)也可以實(shí)現(xiàn)此查詢(xún),示例如下:

   query_map = {"pk:id","p_age:person_age","p_name:person_name"}
   Person.objects.raw("select * from person",translations=query_map)

  raw()方法還支持索引,若只需要第一個(gè)查詢(xún)結(jié)果,則可使用如下形式:

   person = Person.objects.raw("select * from person")[0]

  在查詢(xún)數(shù)據(jù)時(shí),可以使用raw()方法中參數(shù)params為原始SQL語(yǔ)句傳遞查詢(xún)參數(shù),該參數(shù)可以為一個(gè)列表或字典類(lèi)型的數(shù)據(jù)。

  將查詢(xún)條件作為參數(shù)使用raw()方法進(jìn)行查詢(xún),示例如下:

   param = ['person_name']
   p_name = Person.objects.raw("select id,%s from person",param)

  上述語(yǔ)句表示查詢(xún)數(shù)據(jù)表person中的id、person_name字段。

  使用“%(key)s”作為占位符可以為raw()方法的參數(shù)params傳遞一個(gè)字典類(lèi)型的參數(shù),其中key由參數(shù)中的key替換。示例如下:

  param = {"id"=1}
  P_name =Person.objects.raw("select * from person where id=%(id)s',param)

  上述語(yǔ)句表示查詢(xún)數(shù)據(jù)表person中id為1的記錄。

  需要說(shuō)明的是,如果使用的是SQLite數(shù)據(jù)庫(kù),那么參數(shù)params只能以列表形式傳入。

  2.利用游標(biāo)對(duì)象執(zhí)行SQL語(yǔ)句

  雖然使用raw()方法可以通過(guò)模型查詢(xún)到數(shù)據(jù)表中的數(shù)據(jù),但是在實(shí)際開(kāi)發(fā)中還可能需要對(duì)未映射至模型的數(shù)據(jù)進(jìn)行查詢(xún),或更新、插入、刪除,此時(shí)無(wú)法再使用raw()方法,只能繞過(guò)模型直接訪問(wèn)數(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語(yǔ)句。

  例如,使用connection對(duì)象查詢(xún)數(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ì)象的常用方法,它們分別返回查詢(xún)集中的一條/全部記錄。使用fetchone()查詢(xún)一條記錄,示例如下:

   conn.fetchone()

  以上示例代碼將查詢(xún)出一條記錄。

  使用fetchall()查詢(xún)所有記錄,示例如下:

   conn.fetchall()

  以上示例代碼將查詢(xún)出所有記錄。

分享到:
在線咨詢(xún) 我要報(bào)名
和我們?cè)诰€交談!