【发布时间】:2012-09-28 01:06:36
【问题描述】:
我已尝试清理和修改答案here 中的代码以满足我的需要,我只想从模型Reservations 中删除在get 中表示为yy,mm,dd 的日期之前的数据记录。
如果我正确预期 cleanTable/2012/10/5 对路由 ('/cleanTable/([\d]+)/([\d]+)/([\d]+)', CleanTable) 的操作,那么我的代码最多只会删除 50 (10*nlimit) 个数据记录。
顺便说一句,原始代码的作者(他可能不再订阅 SO)声称他完成此代码的主要技巧是“在 html 中包含重定向而不是使用 self.redirect”。
我不熟悉raise Exception 之类的东西,但我的直觉是在for 循环中添加一个raise Exception 或raise StopIteration,然后将其制成while 循环。但我不清楚引发 StopIteration 异常是否真的会导致迭代停止,或者是否需要更多。另外,我不知道如何修改,以便 html 在提前退出时顺利结束。
class CleanTable(BaseHandler):
def get(self, yy,mm,dd):
nlimit=5
iyy=int(yy)
imm=int(mm)
idd=int(dd)
param=date(iyy,imm,idd)
q=Reservations.all(keys_only=True)
q.filter("date < ", dt(iyy,imm,idd))
results = q.fetch(nlimit)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("""
<html>
<meta HTTP-EQUIV="REFRESH" content="url=http://yourapp.appspot.com/cleanTable">
<body>""")
try:
for i in range(10):
db.delete(results)
results = q.fetch(nlimit, len(results))
for r in results:
logging.info("r.name: %s" % r.name)
self.response.out.write("<p> "+str(nlimit)+" removed</p>")
self.response.out.write("""
</body>
</html>""")
except Exception, inst:
logging.info("inst: %s" % inst)
self.response.out.write(str(inst))
【问题讨论】:
-
这看起来像一个非常丑陋的黑客......从您的代码中,我假设您所有实体的键都适合您的应用程序的内存。如果这是真的,更优雅和可靠的方法是使用任务队列 - 对于每个键,使用该键启动一个任务以将其删除。然后工作人员将加载然后执行删除。如果这不起作用,请批处理该过程。如果以后有时间,我会发布示例代码。
-
您可以批量删除( db.delete(keys) )任务中查询的结果实体。一项任务的时间限制为 10 分钟。如果任务每次运行最多删除 10000 个实体,并且您有更多实体要删除,则重复该任务,直到查询结果少于 10000 个实体。你也可以使用mapreduce:developers.google.com/appengine/docs/python/dataprocessing/…
-
当我不知道有多少记录时,我对这段代码的最终使用将是在一个 cron 工作中丢弃旧记录,所以我认为某种 while 循环是合适的。
标签: python google-app-engine exception while-loop