django執行原生SQL查詢的實現
執行原生 SQL 查詢
Django 允許你用兩種方式執行原生 SQL 查詢:
- 你可以使用 Manager.raw() 來 執行原生查詢並返回模型實例。
- 或者完全不用模型層 直接執行自定義 SQL。
1、執行原生查詢
管理器方法 raw() 能用於執行原生 SQL 查詢,就會返回模型實例:
Manager.raw(raw_query, params=None, translations=None)
該方法接受一個原生 SQL 查詢語句,執行它,並返回一個 django.db.models.query.RawQuerySet 實例。這個 RawQuerySet 能像普通的 QuerySet 一樣被迭代獲取對象實例。
1.1 普通查詢
class Person(models.Model): first_name = models.CharField(...) last_name = models.CharField(...) birth_date = models.DateField(...)
然後你可以像這樣執行自定義 SQL:
for p in Person.objects.raw('SELECT * FROM app_person'): # django默認的表名是app名加類名 print(p) # 沒有查詢到就報錯
1.2 將查詢字段映射為模型字段
raw() 字段將查詢語句中的字段映射至模型中的字段。
查詢語句中的字段排序並不重要。換而言之,以下兩種查詢是一致的:
Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM app_person') Person.objects.raw('SELECT last_name, birth_date, first_name, id FROM app_person')
匹配是根據名字來的。這意味著你可以使用 SQL 的 AS 子句將查詢語句中的字段映射至模型中的字段。所以,若你還有一些數據表包含瞭 Person 數據,你可以很方便的將其映射至 Person 實例:
>>> Person.objects.raw('''SELECT first AS first_name, ... last AS last_name, ... bd AS birth_date, ... pk AS id, ... FROM app_person''')
隻要名字對上瞭,模型實例就會被正確創建。
或者,你可以用 raw() 的 translations 參數將查詢語句中的字段映射至模型中的字段。這是一個字典,將查詢語句中的字段名映射至模型中的字段名。例如,上面的查詢也能這樣寫:
>>> name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'} >>> Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
1.3 索引查詢
raw() 支持索引,所以,若你隻需要第一個結果就這樣寫:
>>> first_person = Person.objects.raw('SELECT * FROM app_person')[0]
1.4 將參數傳給 raw()
如果你需要執行參數化的查詢,可以使用 raw() 的 params 參數:
>>> lname = 'Doe' >>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])
params 是一個參數字典。你將用一個列表替換查詢字符串中 %s 占位符,或用字典替換 %(key)s 占位符(其中, key 理所應當由字典 key 替換),不論你使用哪個數據庫引擎。這些占位符會被 params 參數的值替換。
!!!必須以列表形式傳入參數,格式一定是這樣寫,不能寫成字符串
2、直接執行自定義 SQL
繞過模型層。
對象 django.db.connection 代表默認數據庫連接。要使用這個數據庫連接,調用 connection.cursor() 來獲取一個指針對象。然後,調用 cursor.execute(sql, [params]) 來執行該 SQL 和 cursor.fetchone(),或 cursor.fetchall() 獲取結果數據。
from django.db import connection def my_sql(self): with connection.cursor() as cursor: cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz]) cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz]) row = cursor.fetchone() return row
要避免 SQL 註入,你絕對不能在 SQL 字符串中用引號包裹 %s 占位符。
註意,若要在查詢中包含文本的百分號,你需要在傳入參數使用兩個百分號:
cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' AND id = %s", [self.id])
2.1 指定連接數據庫
用 django.db.connections 獲取指定數據庫的連接(和指針)。 django.db.connections 是一個類字典對象,它允許你通過連接別名獲取指定連接:
from django.db import connections with connections['my_db_alias'].cursor() as cursor:
到此這篇關於django執行原生SQL查詢的實現的文章就介紹到這瞭,更多相關django執行原生SQL查詢內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- django中使用原生sql語句的方法步驟
- django中F與Q查詢的使用
- python sqlite3 判斷cursor的結果是否為空的案例
- django模型查詢操作的實現
- Django細致講解多對多使用through自定義中間表方法