我正在尝试更新很多记录,在给定的一分钟最大请求时间内无法完成,因此我需要使用datastore.Cursor,但由于某种原因,返回的游标始终是相同的。因此,每个重定向都使用相同的游标值完成,从而导致每次执行相同的20个数据库更新。
为什么事情不像我想的那样有效?
http.HandleFunc("/fix", func(w, http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
fixUser(c, w, r, "/fix", func() error {
// do the fix here
return nil
})
})
func fixUser(ctx context.Context, w http.ResponseWriter, r *http.Request, path string, fn func(user *User) error) {
q := datastore.NewQuery("users")
c := r.URL.Query().Get("c")
if len(c) > 0 {
cursor, err := datastore.DecodeCursor(c)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
q.Start(cursor)
}
iter := q.Run(ctx)
var cr datastore.Cursor
for i := 0; i < 20; i++ {
var u User
key, err := iter.Next(&u)
if err == datastore.Done {
return
}
if err != nil {
panic(err.Error())
}
cr, _ = iter.Cursor()
log.Debugf(ctx, "Cursor: %v", cr) // always the same value
u.Key = key
fn(&u)
}
pathWithCursor := fmt.Sprintf("%s?c=%s", path, cr.String())
http.Redirect(w, r, pathWithCursor, 301)
}
答案 0 :(得分:1)
我查看了一些自己的游标代码并将其与您的游标代码进行了比较。我看到的主要区别是我使用的是q = q.Start(cursor)
而不是q.start(cursor)
。这应该可以解决您的问题,因为您的查询现在将更新以反映光标指定的位置。如果不将查询存储回q
变量,您的查询将不会更新。