问题 GAE Go - 如何将GetMulti与不存在的实体密钥一起使用?


我发现自己需要做一个 GetMulti 使用一些键存在的操作,但有些实体不存在。

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

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

那我该怎么做呢?我使用“获取或插入”方法,但没有一个。


11477
2018-03-06 16:17


起源



答案:


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
    }
}

15
2018-03-06 19:38



如果使用类型断言,则可以缩短该块。如果我,ok:=错误。(appengine.MultiError); ok {for {...}} - Jeremy Wall
谢谢。这是你的意思吗? - mjibson
是的,你也可以删除else子句,只返回错误一行:-) - Jeremy Wall
在其他情况下,有一个真正的错误,我们想要指出一些问题,所以我认为保持它是有道理的。 - mjibson
啊,是的,因为你仍然需要访问错误的对象。好点子。 - Jeremy Wall


答案:


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
    }
}

15
2018-03-06 19:38



如果使用类型断言,则可以缩短该块。如果我,ok:=错误。(appengine.MultiError); ok {for {...}} - Jeremy Wall
谢谢。这是你的意思吗? - mjibson
是的,你也可以删除else子句,只返回错误一行:-) - Jeremy Wall
在其他情况下,有一个真正的错误,我们想要指出一些问题,所以我认为保持它是有道理的。 - mjibson
啊,是的,因为你仍然需要访问错误的对象。好点子。 - Jeremy Wall


我知道这个话题已经持续了几天,但我想发布一个替代方案,使用 型开关

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
2017-07-12 18:54