2011-11-19 34 views
11

Cách thích hợp để thực hiện cập nhật hàng loạt trên thực thể trong kho dữ liệu của Máy ứng dụng của Google là gì? Nó có thể được thực hiện mà không cần phải lấy các thực thể?Cập nhật hàng loạt trong Google App Engine Datastore

Ví dụ, những gì sẽ là GAE equivilant một cái gì đó như thế này trong SQL:

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

Trả lời

9

Không có một bản dịch trực tiếp. Kho dữ liệu thực sự không có khái niệm cập nhật; tất cả những gì bạn có thể làm là ghi đè các thực thể cũ với một thực thể mới tại cùng một địa chỉ (khóa). Để thay đổi một thực thể, bạn phải lấy nó từ kho dữ liệu, sửa đổi nó cục bộ, và sau đó lưu nó trở lại.

Cũng không tương đương với toán tử LIKE. Trong khi kết hợp ký tự đại diện là có thể với một số thủ thuật, nếu bạn muốn kết hợp '% Salt%' bạn phải đọc từng thực thể duy nhất vào bộ nhớ và thực hiện so sánh chuỗi cục bộ.

Vì vậy, nó sẽ không hoàn toàn sạch sẽ hoặc hiệu quả như SQL. Đây là một sự cân bằng với hầu hết các cửa hàng đối tượng phân tán, và kho dữ liệu cũng không ngoại lệ.

Điều đó nói rằng, the mapper library có sẵn để tạo điều kiện cập nhật hàng loạt như vậy. Thực hiện theo ví dụ và sử dụng một cái gì đó như thế này cho hàm process của bạn:

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

Có các lựa chọn thay thế khác ngoài công cụ lập bản đồ. Mẹo tối ưu hóa quan trọng nhất là cập nhật hàng loạt các bản cập nhật của bạn; không lưu lại từng thực thể được cập nhật riêng lẻ. Nếu bạn sử dụng trình đặt bản đồ và sản lượng, điều này sẽ được xử lý tự động.

+0

Drew- cảm ơn rất nhiều cho các tham chiếu mapper-trông giống như một cái gì đó tôi sẽ muốn tìm hiểu về. – Yarin

2

bạn có thể sử dụng lớp truy vấn, 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

cảm ơn, nhưng không phải là điều này đưa tất cả các đối tượng vào bộ nhớ, và cũng bị hạn chế bởi giới hạn kỷ lục 1000 tối đa? – Yarin

5

Không, nó không thể được thực hiện mà không lấy các thực thể.

Không có điều gì như 'giới hạn kỷ lục tối đa 1000', nhưng tất nhiên là có thời gian chờ trên bất kỳ yêu cầu nào - và nếu bạn có số lượng lớn thực thể cần sửa đổi, một lần lặp đơn giản có thể sẽ bị lỗi. Bạn có thể quản lý điều này bằng cách chia nhỏ nó thành nhiều hoạt động và theo dõi với query cursor hoặc có khả năng bằng cách sử dụng MapReduce framework.

+0

Daniel cảm ơn- ..Có thể tuyên thệ nhậm chức có giới hạn kỷ lục tối đa tại một thời điểm - họ có loại bỏ nó không? – Yarin

+0

Trong trường hợp của tôi, tôi không nhận được "thời gian chờ", tôi nhận được lỗi cụ thể: "Trong khi xử lý yêu cầu này, quá trình xử lý yêu cầu này được tìm thấy là sử dụng quá nhiều bộ nhớ và đã bị chấm dứt.' –

+0

Cho phép tôi để nhấn mạnh rằng MapReduce được thiết kế để giải quyết ít nhất "cả hai" vấn đề của "quá nhiều bộ nhớ" (aka ** lớn **) và "timeout" (aka ** dài chạy **): ['Nó rất hữu ích cho các công việc lớn, dài hạn không thể xử lý trong phạm vi một yêu cầu duy nhất, các tác vụ như: '] (https://github.com/GoogleCloudPlatform/appengine-mapreduce/wiki/1-MapReduce) –

Các vấn đề liên quan