[Django資料庫模型]Django用原始SQL進行Insert/Update操作
阿新 • • 發佈:2019-02-09
一般來說,最好用 Django 自帶的模型來實現這些操作。這裡僅僅只是為了學習使用原始 SQL 而做的練習。
Django 提供了非常方便的資料管理模型 models,可以完成與資料庫的基本操作。但有時,Django 原始的 models 的功能可能會不太夠用,這些情況下可以直接繞過模型直接訪問資料庫。
Django提供兩種方式執行(performing)原始的SQL查詢:
- Manager.raw():執行原始查詢並返回模型例項
- Executing custom SQL directly:直接執行自定義SQL,這種方式可以完全避免資料模型,而是直接執行原始的SQL語句。
先上程式,再解釋。
下面的函式,獲取表單傳遞過來的 POST 資料,然後執行 Insert/Update 操作。
from django.views.decorators.csrf import csrf_exempt from django.db.transaction import commit_on_success import MySQLdb @csrf_exempt @commit_on_success def add_post(request): from django.db import connection, transaction title = request.POST.get('title', False) vicetitle = request.POST.get('vice_title', False) digest = request.POST.get('digest', False) content = request.POST.get('content', False) db = MySQLdb.connect(user='root', db='testdb', passwd='', host='localhost', charset='utf8') #cursor = db.cursor() cursor = connection.cursor() #cursor.execute("INSERT INTO nowamagic (title, vicetitle, digest, content) values (%s, %s, %s, %s)", [title, vicetitle, digest, content]) cursor.execute("UPDATE chika SET title = '3333' WHERE id = '2'") transaction.commit_unless_managed() #transaction.set_dirty() db.close() return render_to_response('test.html', context_instance=RequestContext(request))
一些語句的大概解釋:
- django.db.connection,代表了預設的資料庫連線,
- django.db.transaction,代表預設的資料庫事務。
- counnection.cursor,代表預設資料庫遊標。
- cursor.execute(sql,[params]),執行sql語句。
- cursor.fetchone() 或 cursor.fetchall(),返回查詢的結果。
- transaction.commit_unless_managed(),事務提交,確保資料更改(在更改資料庫時使用,如果查詢操作沒必要使用)
如果你正在使用事務裝飾器(例如 commit_on_success)來修飾檢視和提供事務控制,你不必手動呼叫 transaction.commit_unless_managed(),當然如果你願意的話,可以手動呼叫,但是一般情況下用不著這麼做,這是因為裝飾器會為你自動提交事務。但是,如果你不手動提交修改,你需要使用 transaction.set_dirty() 將事務標識為已髒。
@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()
return render_to_response('template.html', {'row': row})
使用 Django ORM 對資料庫進行修改時,Django 會自動呼叫 set_dirty() 。但如果你使用了原始 SQL ,Django 就無法獲得你的 SQL 是否修改了資料。只有手動呼叫 set_dirty() 才能確保 Django 知曉哪些修改必須被提交。