GAE Go——如何在不存在的实体键中使用GetMulti?

12
我发现自己需要使用一组键进行GetMulti操作,其中一些实体存在,但一些不存在。

我的当前代码如下,返回错误(datastore: no such entity)。

err := datastore.GetMulti(c, keys, infos)

那么我该怎么做呢?我会使用“获取或插入”方法,但这里没有这样的方法。

3个回答

19
在这种情况下,GetMulti 可以返回一个 appengine.MultiError。循环遍历它并查找 datastore.ErrNoSuchEntity。例如:
if err := datastore.GetMulti(c, keys, dst); err != nil {
    if me, ok := err.(appengine.MultiError); ok {
        for i, merr := range me {
            if merr == datastore.ErrNoSuchEntity {
                // keys[i] is missing
            }
        }
    } else {
        return err
    }
}

2
如果使用类型断言,您可以缩短该代码块。如果 me, ok := err.(appengine.MultiError); ok { for { ... } } - Jeremy Wall
谢谢。这是你的意思吗? - mjibson
2
是的,你也可以放弃else子句,只返回err,这样就少了一行代码 :-) - Jeremy Wall
1
在else的情况下,确实存在一个真正的错误,我们希望指示出一些问题,因此我认为保留它是有意义的。 - mjibson
啊,是的,因为你仍然需要访问 err 对象。说得好。 - Jeremy Wall

2

我知道这个话题已经讨论了不止几天,但我想发表一种替代方案,使用类型开关

if err := datastore.GetMulti(c, keys, dst); err != nil {
  switch errt := err.(type) {
  case appengine.MultiError:
    for ix, e := range errt {
      if e == datastore.ErrNoSuchEntity {
        // keys[ix] not found
      } else if e != nil {
        // keys[ix] have error "e"
      }
    }
  default:
    // datastore returned an error that is not a multi-error
  }
}

0

我想分享一下我的答案,展示另一个用例。以下代码将接收任意数量的键,并返回所有有效的键。

// Validate keys
var validKeys []*ds.Key
if err := c.DB.GetMulti(ctx, tempKeys, dst); err != nil {
    if me, ok := err.(ds.MultiError); ok {
        for i, merr := range me {
            if merr == ds.ErrNoSuchEntity {
                continue
            }
            validKeys = append(validKeys, tempKeys[i])
        }
    } else {
        return "", err
    }
} else {
    // All tempKeys are valid
    validKeys = append(validKeys, tempKeys...)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接