Django中如何直接執(zhí)行SQL語句
Django直接執(zhí)行SQL語句
今天在django views.py看到同事寫的代碼里面有段關(guān)于數(shù)據(jù)庫查詢的語句。
因為涉及多個表的查詢,所以django 的models的查詢無法滿足需求,所以直接執(zhí)行了SQL語句。
他是按照下面的方法實現(xiàn)的。
try: connection = MySQLdb.connect(host=SQL_IP, user=SQL_USER, passwd=SQL_PASSWD, db=SQL_DB, charset='utf8') cursor = connection.cursor() cmd_query = query_data(request) data_sort = sort_data(request) cmd = "set session group_concat_max_len = 8000;" cursor.execute(cmd) ......
看到這段代碼,感覺應(yīng)該重復(fù)造了輪子,數(shù)據(jù)庫的鏈接應(yīng)該交由django這個框架處理的。于是查看了下官方文檔。
django.db.connection 就是上面的同事寫的那個connection了。
后面的方法同他的一樣執(zhí)行就是了。即執(zhí)行
connection.cursor() cursor.execute(sql, [params]) cursor.fetchone() or cursor.fetchall()
下面是一個簡單的例子。
from django.db import connection def my_custom_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
如果你項目中有多個數(shù)據(jù)庫的話,django.db.connection也能很方便的選取數(shù)據(jù)庫。
django.db.connections 是一個類字典的結(jié)構(gòu),允許你使用數(shù)據(jù)庫別名獲取connection。
from django.db import connections with connections['my_db_alias'].cursor() as cursor: # Your code here...
使用with作為上下文管理器:
with connection.cursor() as c: c.execute(...)
和下面這段代碼等效
c = connection.cursor() try: c.execute(...) finally: c.close()
注意的問題:
如果你做了更新或者插入操作需要在代碼中使用 :transaction.commit_unless_managed() 來提交數(shù)據(jù)。
或者使用事務(wù)裝飾器(例如 commit_on_success)來修飾視圖和提供事務(wù)控制數(shù)據(jù)提交。
這樣就不用在代碼中調(diào)用transaction.commit_unless_managed()。
但是,如果你不手動提交修改,你需要使用 transaction.set_dirty() 將事務(wù)標識為已臟。
使用 Django ORM 對數(shù)據(jù)庫進行修改時,Django 會自動調(diào)用 set_dirty() 。
但如果你使用了原始 SQL ,Django 就無法獲得你的 SQL 是否修改了數(shù)據(jù)。
只有手動調(diào)用 set_dirty() 才能確保 Django 知曉哪些修改必須被提交。
from django.db.transaction import commit_on_success @commit_on_success def my_custom_sql_view(request, value): from django.db import connection, transaction cursor = connection.cursor() # Data modifying operation cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value]) # Since we modified data, mark the transaction as dirty transaction.set_dirty() # Data retrieval operation. This doesn't dirty the transaction, # so no call to set_dirty() is required. cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value]) row = cursor.fetchone() #transaction.commit_unless_managed() return render_to_response('template.html', {'row': row})
如果不使用
參考文獻:1、https://docs.djangoproject.com/en/2.0/topics/db/sql/
Django底層實現(xiàn)sql語句
在django中我們可以自己手寫底層sql語句,那么如何寫呢?
#導(dǎo)入原生sql模塊 from django.db import connection # 獲取當前用戶關(guān)注課程列表 def get_myflow(request): # 獲取用戶id uid = request.GET.get('id') # 建立游標對象 cursor = connection.cursor() # 鏈表查詢 cursor.execute('select a.username,c.title from user a left join flows b on a.id=b.uid left join course c on b.cid=c.id where a.id = %s'% uid) # 獲取結(jié)果集 result = dictfetchall(cursor) print(result) # 返回結(jié)果 return HttpResponse(json.dumps(result),content_type='application/json')
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python-re中search()函數(shù)的用法詳解(查找ip)
這篇文章主要介紹了Python-re中search()函數(shù)的用法-----查找ip,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03python 實現(xiàn)仿微信聊天時間格式化顯示的代碼
這篇文章主要介紹了python 實現(xiàn)仿微信聊天時間格式化顯示,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-04-04使用Pandas和Matplotlib進行數(shù)據(jù)清洗與可視化的實現(xiàn)步驟
在數(shù)據(jù)科學(xué)領(lǐng)域,數(shù)據(jù)清洗和可視化是構(gòu)建數(shù)據(jù)驅(qū)動解決方案的重要步驟,本文將詳細介紹如何使用Pandas進行數(shù)據(jù)清洗,并結(jié)合Matplotlib進行可視化,文章通過實際代碼示例講解的非常詳細,需要的朋友可以參考下2024-08-08Tensorflow 訓(xùn)練自己的數(shù)據(jù)集將數(shù)據(jù)直接導(dǎo)入到內(nèi)存
這篇文章主要介紹了Tensorflow 訓(xùn)練自己的數(shù)據(jù)集將數(shù)據(jù)直接導(dǎo)入到內(nèi)存,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06Pandas實現(xiàn)groupby分組統(tǒng)計方法實例
在數(shù)據(jù)處理的過程,有可能需要對一堆數(shù)據(jù)分組處理,例如對不同的列進行agg聚合操作(mean,min,max等等),下面這篇文章主要給大家介紹了關(guān)于Pandas實現(xiàn)groupby分組統(tǒng)計方法的相關(guān)資料,需要的朋友可以參考下2023-06-06