英文:
Appengine's datastore Cursor never changes
问题
我正在尝试更新大量记录,但在给定的一分钟最大请求时间内无法完成,所以我需要使用一个datastore.Cursor。但是由于某种原因,返回的游标始终相同。因此,每次重定向都使用相同的游标值,导致每次执行相同的20个数据库更新。
有什么想法,为什么事情不像我想的那样工作?
http.HandleFunc("/fix", func(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
fixUser(c, w, r, "/fix", func() error {
// 在这里进行修复
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) // 总是相同的值
u.Key = key
fn(&u)
}
pathWithCursor := fmt.Sprintf("%s?c=%s", path, cr.String())
http.Redirect(w, r, pathWithCursor, 301)
}
英文:
I am trying to update a lot of records, to which cannot be done within the one minute max request time given, so I need to use a datastore.Cursor, but for some reason the returned cursor is always the same. So each redirect is done with the same cursor value, resulting in the the same 20 database updates being performed each time.
Any ideas to why things aren't working like I would like?
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)
}
答案1
得分: 1
我查看了一些我自己的光标代码,并将其与你的代码进行了比较。我看到的主要区别是我使用 q = q.Start(cursor)
而不是 q.start(cursor)
。这应该可以解决你的问题,因为现在你的查询将会根据光标指定的位置进行更新。如果不将查询重新存储到 q
变量中,你的查询将不会更新。
英文:
I looked at some of my own cursor code and compared it against yours. The main difference I see is that I use q = q.Start(cursor)
rather than q.start(cursor)
. This should fix your problem since your query will now be updated to reflect the position specified by the cursor. Without storing your query back into the q
variable, your query will not update.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论