我尝试在答案here中根据我的需要清理和修改代码,我只想从模型Reservations
中删除get as {中表达的日期之前的数据记录{1}}。
如果我正确地预测yy,mm,dd
对路由cleanTable/2012/10/5
的操作,那么我的代码最多只能删除50(10 * nlimit)个数据记录。
我不熟悉('/cleanTable/([\d]+)/([\d]+)/([\d]+)', CleanTable)
之类的内容,但我的本能是在for循环中将for raise Exception
或raise Exception
添加到for循环中。但是我不清楚是否提高StopIteration异常会导致迭代停止或是否需要更多。此外,我不知道如何修改,以便html在提前退出时顺利结束。
raise StopIteration
答案 0 :(得分:0)
这不是清洁模型的最佳方法。更好的方法是获取实体的所有密钥并创建Task Queues。每个队列将获得需要修改的实体的一批密钥。
另一种方法也是创建一个cron job,它将查询x个最旧的修改实体,修复它们然后再存储它们。
最后,如果您的实体数量如此巨大,您还可以考虑使用Backends。
希望这有帮助。
答案 1 :(得分:0)
这是我的更新例程,它已经转换了500.000个实体。确保在后端实例上运行它(您可以将队列定位到后端实例)。请注意,我正在使用游标,这是您可以始终迭代数据的唯一方法(从不使用偏移!)。
Queue queue = QueueFactory.getQueue("grinderQueue");
queue.add(TaskOptions.Builder.withPayload(new DeferredTask() { //lets generate
private static final long serialVersionUID = 1L;
@Override
public void run() {
String cursor = null;
boolean done = false;
Date now = new Date(1346763868L * 1000L); // 09/04/2012
while(!done) {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Query query = new Query("Venue");
query.setFilter(new FilterPredicate("timeOfLastUpdate", Query.FilterOperator.LESS_THAN,now));
PreparedQuery pq = datastore.prepare(query);
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(1000);
if(cursor != null)
fetchOptions.startCursor(Cursor.fromWebSafeString(cursor));
QueryResultList<Entity> results = pq.asQueryResultList(fetchOptions);
List<Entity> updates = new ArrayList<Entity>();
List<Entity> oldVenueUpdates = new ArrayList<Entity>();
int tuples = 0;
for(Entity en : results) {
tuples++;
try {
if(en.getProperty(Venue.VENUE_KEY) == null)
continue;
Entity newVenue = new Entity("CPVenue",(String)en.getProperty(Venue.VENUE_KEY));
newVenue.setPropertiesFrom(en);
newVenue.removeProperty("timeOfLastVenueScoreCalculation");
newVenue.removeProperty("actionsSinceLastVenueScoreCalculation");
newVenue.removeProperty("venueImageUrl");
newVenue.removeProperty("foursquareId");
newVenue.setProperty("geoCell", GeoCellCalculator.calcCellId(Double.valueOf((String)en.getProperty("lng")), Double.valueOf((String)en.getProperty("lat")),8));
newVenue.setProperty(Venue.TIME_SINCE_LAST_UPDATE, new Date());
updates.add(newVenue);
Venue v = new Venue(newVenue);
//Set timestamp on Venue
en.setProperty("timeOfLastUpdate", now);
oldVenueUpdates.add(en);
}catch(Exception e) {
logger.log(Level.WARNING,"",e);
}
}
done = tuples == 0;
tuples = 0;
if(results.getCursor() != null)
cursor = results.getCursor().toWebSafeString();
else
done = true;
System.out.println("Venue Conversion LOOP updates.. " + updates.size() + " cursor " + cursor);
datastore.put(updates);
datastore.put(oldVenueUpdates);
}
System.out.println("Venue Conversion DONE");
}}));