在Django中如何執(zhí)行原生SQL查詢詳解
在Django中,執(zhí)行原生SQL查詢
1. 使用raw()方法
raw() 方法允許你執(zhí)行原生SQL查詢并返回模型實例:
from myapp.models import Person
# 基本查詢
people = Person.objects.raw('SELECT * FROM myapp_person WHERE age > %s', [18])
# 遍歷結(jié)果
for person in people:
print(person.name, person.age)
# 帶參數(shù)的查詢
people = Person.objects.raw(
'SELECT * FROM myapp_person WHERE age BETWEEN %s AND %s',
[20, 30]
)
2. 使用數(shù)據(jù)庫連接直接執(zhí)行SQL
基本用法:
from django.db import connection
def my_custom_sql():
with connection.cursor() as cursor:
# 執(zhí)行查詢
cursor.execute("SELECT * FROM myapp_person WHERE age > %s", [25])
# 獲取所有結(jié)果
rows = cursor.fetchall()
# 或者逐行獲取
# row = cursor.fetchone()
# rows = cursor.fetchmany(size=10)
return rows
返回字典格式的結(jié)果:
from django.db import connection
def dictfetchall(cursor):
"""將游標結(jié)果轉(zhuǎn)換為字典列表"""
columns = [col[0] for col in cursor.description]
return [
dict(zip(columns, row))
for row in cursor.fetchall()
]
def my_custom_sql():
with connection.cursor() as cursor:
cursor.execute("SELECT id, name, age FROM myapp_person")
results = dictfetchall(cursor)
return results
3. 使用多個數(shù)據(jù)庫
如果你的項目配置了多個數(shù)據(jù)庫:
from django.db import connections
def query_multiple_dbs():
# 使用默認數(shù)據(jù)庫
with connections['default'].cursor() as cursor:
cursor.execute("SELECT * FROM table1")
# 處理結(jié)果
# 使用其他數(shù)據(jù)庫
with connections['other_db'].cursor() as cursor:
cursor.execute("SELECT * FROM table2")
# 處理結(jié)果
4. 執(zhí)行寫操作(INSERT/UPDATE/DELETE)
from django.db import connection
def update_data():
with connection.cursor() as cursor:
# INSERT
cursor.execute(
"INSERT INTO myapp_person (name, age) VALUES (%s, %s)",
['John', 30]
)
# UPDATE
cursor.execute(
"UPDATE myapp_person SET age = %s WHERE name = %s",
[31, 'John']
)
# DELETE
cursor.execute(
"DELETE FROM myapp_person WHERE age < %s",
[18]
)
5. 事務處理
from django.db import transaction, connection
@transaction.atomic
def complex_operation():
with connection.cursor() as cursor:
try:
# 一系列SQL操作
cursor.execute("UPDATE accounts SET balance = balance - %s", [100])
cursor.execute("UPDATE accounts SET balance = balance + %s", [100])
except Exception as e:
# 出錯時會自動回滾
print(f"Error: {e}")
6. 實用的封裝函數(shù)
from django.db import connection
def execute_query(query, params=None, return_dict=True):
"""
執(zhí)行SQL查詢的通用函數(shù)
"""
with connection.cursor() as cursor:
cursor.execute(query, params or [])
if query.strip().upper().startswith('SELECT'):
if return_dict:
columns = [col[0] for col in cursor.description]
return [dict(zip(columns, row)) for row in cursor.fetchall()]
else:
return cursor.fetchall()
else:
# 對于非SELECT查詢,返回受影響的行數(shù)
return cursor.rowcount
# 使用示例
results = execute_query(
"SELECT name, age FROM myapp_person WHERE age > %s",
[25]
)

注意事項
SQL注入防護:始終使用參數(shù)化查詢,不要直接拼接字符串
# ? 安全:使用參數(shù)化查詢 cursor.execute("SELECT * FROM users WHERE username = %s", [username]) # ? 危險:字符串拼接(SQL注入風險) cursor.execute(f"SELECT * FROM users WHERE username = '{username}'") # ? 危險:直接傳遞用戶輸入 cursor.execute("SELECT * FROM users WHERE username = %s" % username)表名引用:在SQL中使用實際的數(shù)據(jù)庫表名,而不是模型名
性能考慮:原生SQL通常更快,但失去了Django ORM的一些便利功能;使用直接連接:需要最高性能、復雜查詢或跨表查詢
數(shù)據(jù)庫兼容性:如果你使用多個數(shù)據(jù)庫后端,要注意SQL語法的差異
這些方法讓你在需要優(yōu)化性能或執(zhí)行復雜查詢時,能夠靈活地使用原生SQL,同時保持代碼的安全性和可維護性。
總結(jié)
到此這篇關(guān)于在Django中如何執(zhí)行原生SQL查詢的文章就介紹到這了,更多相關(guān)Django執(zhí)行原生SQL查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中sort()和sorted()的區(qū)別及用法實例
我們通常會遇到對數(shù)據(jù)庫中的數(shù)據(jù)進行排序的問題,下面這篇文章主要給大家介紹了關(guān)于python中sort()和sorted()的區(qū)別及用法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-06-06
一文講解Python和PyTorch的核心區(qū)別(零基礎(chǔ)秒懂)
PyTorch最近幾年可謂大火,相比于TensorFlow,PyTorch對于Python初學者更為友好,更易上手,下面這篇文章主要介紹了Python和PyTorch核心區(qū)別的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2026-01-01
在python下使用tensorflow判斷是否存在文件夾的實例
今天小編就為大家分享一篇在python下使用tensorflow判斷是否存在文件夾的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06
Python使用pdfminer.six實現(xiàn)精準控制PDF文本布局
pdfminer.six是一款強大的Python庫,專注于PDF文檔的精細解析,提供字符級定位和布局控制能力,下面小編就和大家詳細介紹一下它的具體用法吧2026-04-04
python如何通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容
這篇文章主要介紹了python通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容的操作方法,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02
Python使用Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的方法
很多 Python 初學者學完基礎(chǔ)語法后,都會遇到一個很實際的問題:怎么把網(wǎng)頁里的數(shù)據(jù)穩(wěn)定地提取下來,變成自己能處理的結(jié)構(gòu)化數(shù)據(jù),Scrapy 是 Python 生態(tài)里非常經(jīng)典的爬蟲框架,本文給大家介紹了Python使用Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的方法,需要的朋友可以參考下2026-05-05

