2011-11-19 111 views
11

對Google App Engine數據存儲中的實體執行批量更新的正確方法是什麼?它可以在不需要檢索實體的情況下完成嗎?Google App Engine數據存儲中的批量更新

例如,這將是GAE equivilant到像這樣的SQL:

UPDATE dbo.authors 
SET city = replace(city, 'Salt', 'Olympic') 
WHERE city LIKE 'Salt%'; 

回答

9

沒有直接翻譯。數據存儲真的沒有更新的概念;你所能做的就是在同一個地址(關鍵字)上用一個新實體覆蓋舊實體。要更改實體,您必須從數據存儲中獲取它,在本地修改它,然後將其保存回去。

這裏也沒有LIKE操作符的等價物。儘管通配符後綴匹配可能會有一些技巧,但如果要匹配'%Salt%',則必須將每個實體都讀入內存,並在本地執行字符串比較。

所以它不會像SQL一樣乾淨或高效。這是大多數分佈式對象存儲的折衷,數據存儲也不例外。

也就是說,the mapper library可用於促進此批量更新。按照例子,用這樣的事情你process功能:

def process(entity): 
    if entity.city.startswith('Salt'): 
    entity.city = entity.city.replace('Salt', 'Olympic') 
    yield op.db.Put(entity) 

有除了映射其他替代品。最重要的優化技巧是批量更新;不要單獨保存每個更新的實體。如果你使用mapper和yield puts,這將自動處理。

+0

Drew-非常感謝mapper引用 - 看起來像我將要學習的東西。 – Yarin

5

不,不能在沒有檢索實體的情況下完成。

有沒有'1000最大記錄限制'這樣的事情,但是當然對任何一個請求都有超時 - 如果你有大量的實體需要修改,一個簡單的迭代可能會犯這種情況。您可以通過將其分成多個操作並跟蹤query cursor或可能使用MapReduce framework來進行管理。

+0

丹尼爾謝謝 - ..可以發誓,在一個點上有一個最大限度的記錄 - 他們擺脫它嗎? – Yarin

+0

在我的情況下,我沒有得到一個「超時」本身,我得到了具體的錯誤:'在處理這個請求時,處理這個請求的進程被發現使用了太多的內存並被終止.' –

+0

允許我強調MapReduce的目的至少是解決「太多內存」(aka ** large **)和「超時」(aka **長期運行**)的問題:['它對於大量長時間運行的作業,無法在單個請求範圍內處理,例如:'](https://github.com/GoogleCloudPlatform/appengine-mapreduce/wiki/1-MapReduce) –

相關問題