2015-07-12 59 views
0

我對web2py比較新,所以請裸露在我身邊。web2py/DAL - db.commit()是否讓您不需要多次編輯數據庫?

考慮這個表

db.define_table('people' , Field('name')) 

我的理解是,我可以在這樣的數據庫更新記錄:

選項1:

for row in db(db.people).select(): 
    row.update_record(name='Bob') 

選項2:

for row in db(db.people).select(id): 
    db(db.people.id == row.id).update(name='Bob') 
db.commit() 

有什麼不同? .commit()命令是否基本上一次執行所有更改,從而在更新期間阻止數據庫訪問?雖然選項1更新每個記錄在一段時間,因此在這段時間內可以明確指出數據庫被寫在update_record命令之間?

謝謝

EDIT1

這是我的(可能是不正確的)的理解是db.commit()需要如果上述代碼(選項2)被放置在模塊而不是控制器中,因此db.commit()命令。

回答

0

web2py將每個HTTP請求包裝在數據庫事務中。如果請求期間發生異常,事務將被回滾。否則,在請求結束時,在返回響應之前,事務將被提交(因此當時將提交所有插入/更新操作)。

如果您在應用程序代碼中明確地調用db.commit(),那麼該事務將立即提交,而不是等到請求結束。任何後續操作都將成爲新交易的一部分。

在上述兩種情況下,所有更新都將同時提交。唯一的區別是,在第一種情況下,提交將在返回HTTP響應之前由框架發出(假設沒有觸發回滾的中介異常),並且在第二種情況下,提交在運行後立即發生更新的循環。

在選項2中,如果您在循環內移動了db.commit()調用,那麼確實會一次提交更新,而不是一次提交一次。

另外,請注意,要更新記錄,您不需要先選擇它,並且如果要將相同更新應用於多條記錄,則不需要一次更新一條記錄,而是可以改爲更新應用到代表所有記錄的DAL集對象:

db(db.people.id > 0).update(name='Bob') 

上面定義了一組在db.people表中的記錄(在這種情況下,所有的記錄),然後更新所有的「名稱」字段的記錄。此操作不涉及從數據庫中選擇任何記錄。

+0

謝謝,我有點困惑。你是說選項1和選項2是否相同?我認爲'row.update_record'立即提交更改,而'set.update'等待'db。提交()'無論是由於控制器還是像我的示例一樣的手動操作。此外,燁我知道您建議的多重更新方法,但在我的真實情況下,每個記錄更新與它自己的價值。 – evan54

+0

不,row.update_record不立即提交。也許你指的是'row.update'和'row.update_record'之間的區別。前者更新'row'對象本身,但對數據庫記錄沒有影響,而後者更新數據庫(但實際更新直到請求結束纔會提交)。 – Anthony