2011-11-19 2 views
11

Google App Engine Datastore의 엔티티에서 대량 업데이트를 수행하는 적절한 방법은 무엇입니까? 엔터티를 검색하지 않고도 완료 할 수 있습니까? 예를 들어Google App Engine Datastore의 대량 업데이트

는 것이 무엇 GAE는 SQL이 같은 것으로 equivilant :

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) 

. 가장 중요한 최적화 팁은 업데이트를 배치하는 것입니다. 각 업데이트 된 엔티티를 개별적으로 저장하지 마십시오. 매퍼와 산출물 풋을 사용하면 자동으로 처리됩니다.

+0

Drew- 매퍼 참조 용으로 대단히 감사합니다. 배울 점이있는 것처럼 보입니다. – Yarin

2

가 쿼리 클래스를 사용할 수 있습니다, 직접 번역이 없습니다 http://code.google.com/appengine/docs/python/datastore/queryclass.html

query = authors.all().filter('city >', 'Salt').fetch() 
for record in query: 
    record.city = record.city.replace('Salt','Olympic') 
+2

감사합니다,하지만이 모든 개체를 메모리에 가져 오는 것은 아니며 1000 최대 레코드 제한으로 제한됩니까? – Yarin

5

아니요, 엔터티를 검색하지 않으면 수행 할 수 없습니다.

'1000 최대 레코드 한도'와 같은 것은 없지만 모든 단일 요청에 대해 시간 초과가 있습니다. 그리고 수정할 많은 양의 엔티티가있는 경우 간단한 반복이 문제가 될 것입니다. query cursor 또는 잠재적으로 MapReduce framework을 사용하여 여러 작업으로 분할하고 추적하여이 문제를 관리 할 수 ​​있습니다.

+0

Daniel thanks- .. 최대 기록 한도가 한 곳에서 있었다고 맹세했을까요? – Yarin

+0

필자의 경우 "시간 제한"을 얻지 못했습니다. 특정 오류가 있습니다. '이 요청을 처리하는 동안이 요청을 처리 한 프로세스가 너무 많은 메모리를 사용하여 종료되었습니다.' –

+0

허용 MapReduce가 적어도 "너무 많은 메모리"(일명 ** 큰 **)와 "타임 아웃"(일명 ** 장기 실행 **)의 문제를 "둘 다"해결하도록 설계되었다는 것을 강조하기 위해 : 단일 요청의 범위 내에서 처리 할 수없는 대규모의 장기 실행 작업 :'(https://github.com/GoogleCloudPlatform/appengine-mapreduce/wiki/1-MapReduce) –