我在go-appengine中使用了带有数据存储的命名空间,大致如下:
func getThing() *Thing {
nctx := appengine.Namespace(ctx, "whatever")
thing := Thing{}
key, err := datastore.Get(nctx, key, &thing)
if err != nil {
return nil, err
}
return thing, nil
}
很简单,对吧?不幸的是,如果事实证明,如果 nctx 的命名空间与键的不匹配,它无论如何都会愉快地获取对象。AFAICT,无法手动获取密钥的"命名空间"字段以手动验证它。这对我们的应用程序很重要,因为我们有来自 Web 客户端的密钥,在某些边缘情况下,这些密钥可能与错误的命名空间相关联。
OTOH,如果我使用 Thing
的键作为祖先进行查询,数据存储(适当地)会返回错误,因为祖先的命名空间与上下文(形式为 query namespace is 'bar' but ancestor namespace is 'foo'
)之间的命名空间不匹配。
我是否缺少有关数据存储获取/查询和命名空间的预期约束的内容,或者这听起来像是一个错误?
我假设您正在传递编码密钥,而不仅仅是它们的 ID?如果使用datastore.NewKey
创建密钥,则传递给该密钥的上下文将设置密钥的命名空间(除非还有父级,在这种情况下将使用其命名空间)。
就意图而言,此行为等效于 python API - 在namespace_mananger
上设置不同的命名空间时,可以获取从urlsafe字符串创建的密钥,但是如果您仅通过指定种类和id来创建密钥,则使用当前设置的命名空间。
不过,为命名空间提供一个 getter 会很好,所以你至少可以在反序列化后进行验证......