首頁常見問題正文

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

更新時間:2023-01-30 來源:黑馬程序員 瀏覽量:

IT培訓班

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

  1.使用Manager.raw()方法執(zhí)行SQL查詢語句

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

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

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

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

 ?、賠aw_query:表示原始的SQL語句。

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

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

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

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

  以上代碼等價于“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ū)分模型實例,因此,raw()方法的原始SQL查詢語句中必須包含主鍵,否則會拋出invalidQuery異常。

  raw()方法根據(jù)字段名稱查詢數(shù)據(jù),raw()方法中的SQL語句可以使用as關鍵字為字段設置別名。示例如下:

   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ù)也可以實現(xiàn)此查詢,示例如下:

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

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

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

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

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

   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傳遞一個字典類型的參數(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ù)庫,那么參數(shù)params只能以列表形式傳入。

  2.利用游標對象執(zhí)行SQL語句

  雖然使用raw()方法可以通過模型查詢到數(shù)據(jù)表中的數(shù)據(jù),但是在實際開發(fā)中還可能需要對未映射至模型的數(shù)據(jù)進行查詢,或更新、插入、刪除,此時無法再使用raw()方法,只能繞過模型直接訪問數(shù)據(jù)庫。

  django.db.conneciton提供默認數(shù)據(jù)庫連接,使用connection.cursor()方法可以獲取數(shù)據(jù)庫游標對象,使用游標對象的execute()方法可以執(zhí)行原始的SQL語句。

  例如,使用connection對象查詢數(shù)據(jù)表person中所有數(shù)據(jù),示例如下:

   from django.db import connection
   conn = connection.cursor()
   conn.execute('select * from person')

  fetchone()與fetchall()也是數(shù)據(jù)庫游標對象的常用方法,它們分別返回查詢集中的一條/全部記錄。使用fetchone()查詢一條記錄,示例如下:

   conn.fetchone()

  以上示例代碼將查詢出一條記錄。

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

   conn.fetchall()

  以上示例代碼將查詢出所有記錄。

分享到:
在線咨詢 我要報名
和我們在線交談!