1. 程式人生 > >[Django資料庫模型]Django用原始SQL進行Insert/Update操作

[Django資料庫模型]Django用原始SQL進行Insert/Update操作

一般來說,最好用 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 知曉哪些修改必須被提交。