我是Google App Engine的新手,遇到了数据存储的一些问题。
我写了一个测试GaeDatastore_test.go来测试datastore.Query.GetAll方法见下文
package persist
import (
"fmt"
"testing"
"appengine/aetest"
"appengine/datastore"
)
type Mock struct {
Name string
}
func TestAll(t *testing.T) {
ctx, _ := aetest.NewContext(nil)
defer ctx.Close()
d := &Mock{
"hello",
}
fmt.Println(datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "test", nil), d))
fmt.Println(datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "test", nil), d))
fmt.Println(datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "test", nil), d))
q := datastore.NewQuery("test")
var ms []Mock
q.GetAll(ctx, &ms)
fmt.Printf("%#v", ms)
}
当我使用
运行测试文件时goapp测试
它不会返回我存储的3个实体。 我可以在调用datastore.Put后看到键返回,我可以使用datastore.Get使用键检索它们。但是' ms'永远都是零。
然后我尝试使用
初始化ms使([]素,10)
但它没有太大的区别,数据仍未通过。
我查了query.go source file。在内部,它使用loadEntity,这与Get / GetMulti使用的方法相同,并使用append将元素推送到切片。 ms是零,这很奇怪。
客户端正在连接到模拟GAE环境的Python服务器。有人可以帮忙吗?
答案 0 :(得分:8)
我认为这是因为您正在进行跨组查询,并且尚未将写入应用于数据存储。开发服务器模拟类似生产的写可见性。如果您不在事务或实体组中,查询将不会立即显示结果。
来自文档,
写操作在Commit阶段后立即返回,然后Apply阶段异步发生。
和
...当下列之一时,应用前滚完成 发生:
定期数据存储区扫描检查未完成的提交作业并应用 他们。某些操作(获取,放置,删除和祖先查询) 使用受影响的实体组会导致任何已更改 承诺但尚未申请在继续之前完成 新的行动。
和,
因为数据存储获取并且祖先查询应用任何未完成的查询 在执行之前修改,这些操作总是看到一个 所有先前成功交易的一致视图。这意味着 get操作(通过其键查找更新的实体)是 保证能看到该实体的最新版本。
有关这些引号的来源以及有关写入和数据可见性规则的更多详细信息,请参阅:https://developers.google.com/appengine/docs/go/datastore/#Go_Datastore_writes_and_data_visibility
以下是代码的修改版本,在每次放置后对返回的密钥执行Get。 Get()强制要应用该键。这可确保您的GetAll查询将返回所有测试实体。
package persist
import (
"fmt"
"testing"
"appengine/aetest"
"appengine/datastore"
)
type Mock struct {
Name string
}
func TestAll(t *testing.T) {
ctx, _ := aetest.NewContext(nil)
defer ctx.Close()
d := &Mock{
"hello",
}
for i := 0; i < 3; i++ {
k, err := datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "test", nil), d)
fmt.Println(k, err)
datastore.Get(ctx, k, nil)
}
q := datastore.NewQuery("test")
var ms []Mock
q.GetAll(ctx, &ms)
fmt.Printf("%#v", ms)
}