1. shelve物件的持久存盤
不需要關系資料庫時,可以用shelve模塊作為持久存盤Python物件的一個簡單的選擇,類似于字典,shelf按鍵訪問,值將被pickled并寫至由dbm創建和管理的資料庫,
1.1 創建一個新shelf
使用shelve最簡單的方法就是利用DbfilenameShelf類,它使用dbm存盤資料,這個類可以直接使用,也可以通過呼叫shelve.open()來使用,
import shelve with shelve.open('test_shelf.db') as s: s['key1'] = { 'int': 10, 'float': 9.5, 'string': 'Sample data', }
再次訪問這個資料,可以打開shelf,并像字典一樣使用它,
import shelve with shelve.open('test_shelf.db') as s: existing = s['key1'] print(existing)
運行這兩個示例腳本會生成以下輸出,

dbm模塊不支持多個應用同時寫同一個資料庫,不過它支持并發的只讀客戶,如果一個客戶沒有修改shelf,則可以通過傳入flag='r'來告訴shelve以只讀方式打開資料庫,
import dbm import shelve with shelve.open('test_shelf.db', flag='r') as s: print('Existing:', s['key1']) try: s['key1'] = 'new value' except dbm.error as err: print('ERROR: {}'.format(err))
如果資料庫作為只讀資料源打開,并且程式試圖修改資料庫,那么便會生成一個訪問錯誤例外,具體的例外型別取決于創建資料庫時dbm選擇的資料庫模塊,

1.2 寫回
默認的,shelf不會跟蹤對可變物件的修改,這說明,如果存盤在shelf中的一個元素的內容有變化,那么shelf必須再次存盤整個元素來顯式的更新,
import shelve with shelve.open('test_shelf.db') as s: print(s['key1']) s['key1']['new_value'] = 'this was not here before' with shelve.open('test_shelf.db', writeback=True) as s: print(s['key1'])
在這個例子中,沒有再次存盤'key1'的相應字典,所以重新打開shelf時,修改不會保留,

對于shelf中存盤的可變物件,要想自動捕獲對它們的修改,可以在打開shelf時啟用寫回(writeback),writeback標志會讓shelf使用記憶體中快取以記住從資料庫獲取的所有物件,shelf關閉時每個快取物件也被寫回到資料庫,
import shelve import pprint with shelve.open('test_shelf.db', writeback=True) as s: print('Initial data:') pprint.pprint(s['key1']) s['key1']['new_value'] = 'this was not here before' print('\nModified:') pprint.pprint(s['key1']) with shelve.open('test_shelf.db', writeback=True) as s: print('\nPreserved:') pprint.pprint(s['key1'])
盡管這會減少程式員犯錯的機會,并且使物件持久存盤更透明,但是并非所有情況都有必要使用寫回模式,打開shelf時快取會消耗額外的內容,關閉shelf時會暫時將各個快取物件寫回到資料庫,這會減慢應用的速度,所有快取的物件都要寫回資料庫,因為無法區分它們是否有修改,如果應用讀取的資料多于寫的資料,那么寫回就會影響性能而沒有太大意義,

1.3 特定shelf型別
之前的例子都使用了默認的shelf實作,可以使用shelve.open()而不是直接使用某個shelf實作,這是一種常用的用法,特別是使用什么型別的資料庫來存盤資料并不重要時,不過,有些情況下資料庫格式會很重要,在這些情況下,可以直接使用DbfilenameShelf或BsdDbshelf,或者甚至可以派生Shelf來得到一個定制解決方案,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/167467.html
標籤:Python
