我在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'
)。
我是否遗漏了有关数据存储区提取/查询和命名空间的预期约束,或者这听起来像是一个错误?
答案 0 :(得分:1)
我假设您传递的是编码密钥,而不仅仅是他们的ID?如果使用datastore.NewKey
创建密钥,则传递给它的上下文将设置密钥的名称空间(除非还有父项,在这种情况下将使用其名称空间)。
就意图而言,此行为等同于python API - 可以在namespace_mananger
上设置不同的命名空间时获取从urlsafe字符串创建的密钥,但使用当前设置的命名空间如果您通过仅指定种类和ID来创建密钥。
使用命名空间的getter会很好,所以你至少可以在反序列化后验证...