如何删除Go上应用程序引擎中的所有Blob?
答
appengine上的blobstore API无法执行此操作。而是使用数据存储来获取__BlobInfo__
实体,如appengine.BlobInfo
。尽管API宣称拥有BlobKey field,但它并未填充。而是使用返回键的字符串ID并将其转换为appengine.BlobKey
,然后您可以将其传递给blobstore.Delete
。
下面是“/ tasks/delete-blobs”中的处理程序,一次删除20k个blob,直到它们全部被删除。另外请注意,这里不使用游标。我怀疑__BlobInfo__
是特殊的,不支持游标。 (当我试图使用它们时,他们什么都没做。)
func DeleteBlobs(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
c = appengine.Timeout(c, time.Minute)
q := datastore.NewQuery("__BlobInfo__").KeysOnly()
it := q.Run(ctx)
wg := sync.WaitGroup{}
something := false
for _i := 0; _i < 20; _i++ {
var bk []appengine.BlobKey
for i := 0; i < 1000; i++ {
k, err := it.Next(nil)
if err == datastore.Done {
break
} else if err != nil {
c.Errorf("err: %v", err)
continue
}
bk = append(bk, appengine.BlobKey(k.StringID()))
}
if len(bk) == 0 {
break
}
go func(bk []appengine.BlobKey) {
something = true
c.Errorf("deleteing %v blobs", len(bk))
err := blobstore.DeleteMulti(ctx, bk)
if err != nil {
c.Errorf("blobstore delete err: %v", err)
}
wg.Done()
}(bk)
wg.Add(1)
}
wg.Wait()
if something {
taskqueue.Add(c, taskqueue.NewPOSTTask("/tasks/delete-blobs", nil), "")
}
}