在Django中如何執(zhí)行原生SQL查詢?cè)斀?/h1>
更新時(shí)間:2025年10月21日 10:02:18 作者:唐古烏梁海
Django框架作為Python中一個(gè)強(qiáng)大的Web開發(fā)框架,提供了豐富的ORM功能,使得開發(fā)者能夠通過Python對(duì)象來操作數(shù)據(jù)庫,這篇文章主要介紹了在Django中如何執(zhí)行原生SQL查詢的相關(guān)資料,需要的朋友可以參考下
在Django中,執(zhí)行原生SQL查詢
1. 使用raw()方法
raw() 方法允許你執(zhí)行原生SQL查詢并返回模型實(shí)例:
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):
"""將游標(biāo)結(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. 使用多個(gè)數(shù)據(jù)庫
如果你的項(xiàng)目配置了多個(gè)數(shù)據(jù)庫:
from django.db import connections
def query_multiple_dbs():
# 使用默認(rèn)數(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. 事務(wù)處理
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:
# 出錯(cuò)時(shí)會(huì)自動(dòng)回滾
print(f"Error: {e}")
6. 實(shí)用的封裝函數(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:
# 對(duì)于非SELECT查詢,返回受影響的行數(shù)
return cursor.rowcount
# 使用示例
results = execute_query(
"SELECT name, age FROM myapp_person WHERE age > %s",
[25]
)

注意事項(xiàng)
SQL注入防護(hù):始終使用參數(shù)化查詢,不要直接拼接字符串
# ? 安全:使用參數(shù)化查詢
cursor.execute("SELECT * FROM users WHERE username = %s", [username])
# ? 危險(xiǎn):字符串拼接(SQL注入風(fēng)險(xiǎn))
cursor.execute(f"SELECT * FROM users WHERE username = '{username}'")
# ? 危險(xiǎn):直接傳遞用戶輸入
cursor.execute("SELECT * FROM users WHERE username = %s" % username)
表名引用:在SQL中使用實(shí)際的數(shù)據(jù)庫表名,而不是模型名
性能考慮:原生SQL通常更快,但失去了Django ORM的一些便利功能;使用直接連接:需要最高性能、復(fù)雜查詢或跨表查詢
數(shù)據(jù)庫兼容性:如果你使用多個(gè)數(shù)據(jù)庫后端,要注意SQL語法的差異
這些方法讓你在需要優(yōu)化性能或執(zhí)行復(fù)雜查詢時(shí),能夠靈活地使用原生SQL,同時(shí)保持代碼的安全性和可維護(hù)性。
總結(jié)
到此這篇關(guān)于在Django中如何執(zhí)行原生SQL查詢的文章就介紹到這了,更多相關(guān)Django執(zhí)行原生SQL查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
python中sort()和sorted()的區(qū)別及用法實(shí)例
我們通常會(huì)遇到對(duì)數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行排序的問題,下面這篇文章主要給大家介紹了關(guān)于python中sort()和sorted()的區(qū)別及用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下 2022-06-06
-
一文講解Python和PyTorch的核心區(qū)別(零基礎(chǔ)秒懂)
PyTorch最近幾年可謂大火,相比于TensorFlow,PyTorch對(duì)于Python初學(xué)者更為友好,更易上手,下面這篇文章主要介紹了Python和PyTorch核心區(qū)別的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下 2026-01-01
-
Pycharm同步遠(yuǎn)程服務(wù)器調(diào)試的方法步驟
這篇文章主要介紹了Pycharm同步遠(yuǎn)程服務(wù)器調(diào)試,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧 2020-11-11
-
在python下使用tensorflow判斷是否存在文件夾的實(shí)例
今天小編就為大家分享一篇在python下使用tensorflow判斷是否存在文件夾的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 2019-06-06
-
Python使用pdfminer.six實(shí)現(xiàn)精準(zhǔn)控制PDF文本布局
pdfminer.six是一款強(qiáng)大的Python庫,專注于PDF文檔的精細(xì)解析,提供字符級(jí)定位和布局控制能力,下面小編就和大家詳細(xì)介紹一下它的具體用法吧 2026-04-04
-
python如何通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容
這篇文章主要介紹了python通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容的操作方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2023-02-02
-
python實(shí)現(xiàn)類的靜態(tài)變量用法實(shí)例
這篇文章主要介紹了python實(shí)現(xiàn)類的靜態(tài)變量用法,實(shí)例分析了Python中基于數(shù)組實(shí)現(xiàn)靜態(tài)隊(duì)列的相關(guān)使用技巧,需要的朋友可以參考下 2015-05-05
-
Python使用Scrapy抓取和解析網(wǎng)頁數(shù)據(jù)的方法
很多 Python 初學(xué)者學(xué)完基礎(chǔ)語法后,都會(huì)遇到一個(gè)很實(shí)際的問題:怎么把網(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
最新評(píng)論
在Django中,執(zhí)行原生SQL查詢
1. 使用raw()方法
raw() 方法允許你執(zhí)行原生SQL查詢并返回模型實(shí)例:
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):
"""將游標(biāo)結(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. 使用多個(gè)數(shù)據(jù)庫
如果你的項(xiàng)目配置了多個(gè)數(shù)據(jù)庫:
from django.db import connections
def query_multiple_dbs():
# 使用默認(rèn)數(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. 事務(wù)處理
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:
# 出錯(cuò)時(shí)會(huì)自動(dòng)回滾
print(f"Error: {e}")
6. 實(shí)用的封裝函數(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:
# 對(duì)于非SELECT查詢,返回受影響的行數(shù)
return cursor.rowcount
# 使用示例
results = execute_query(
"SELECT name, age FROM myapp_person WHERE age > %s",
[25]
)

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

