为了账号安全,请及时绑定邮箱和手机立即绑定

在 golang 中使用 datastore.GetAll 没有得到结果

在 golang 中使用 datastore.GetAll 没有得到结果

Go
绝地无双 2022-01-04 15:42:18
我有两个功能:一个将实体写入数据存储,另一个假设检索它们。当我datastore.GetAll()在检索中使用函数时,它不返回任何结果。我确实有一个测试来验证写作似乎工作正常。关于为什么检索不起作用的任何想法?这是应用程序代码:package trackerimport (   "fmt"   "appengine"   "appengine/datastore")type User struct {    Email string}func createUser(ctx appengine.Context, email string) (*datastore.Key, error) {    u := &User{        Email: email,        }    incompleteKey := datastore.NewIncompleteKey(ctx, "User", nil)    key, err := datastore.Put(ctx, incompleteKey, u)    if err != nil {        return key, err    }    return key, nil}func getUser(ctx appengine.Context, email string) (u *User, e error) {    users := []User{}    q := datastore.NewQuery("User").Filter("Email", email)    keys, err := q.GetAll(ctx, &users)    if err != nil {        return nil, err    }    fmt.Printf("KEYS: %v", keys)    return &users[0], nil}这是测试代码:package trackerimport (    "fmt"    "testing"    "appengine/datastore"    "appengine/aetest")// This test is passing.func TestCreateUser(t *testing.T) {    ctx, err := aetest.NewContext(nil)    if err != nil {        t.Fatal(err)    }    defer ctx.Close()    email := "testing@testing.go"    newKey, err := createUser(ctx, email)    if err != nil {        t.Errorf("Failed to create a new user: %v", err)    }    u := User{}    datastore.Get(ctx, newKey, &u)    if u.Email != email {        t.Errorf("Expected email to be %s, found %v.", email, u.Email)    }}func TestGetUser(t *testing.T) {    ctx, err := aetest.NewContext(nil)    if err != nil {        t.Fatal(err)    }    defer ctx.Close()    email := "testing@testing.go"    newKey, err := createUser(ctx, email)    fmt.Printf("key, %v; ", newKey)    u, err := getUser(ctx, newKey)    fmt.Printf("user, %v; error: %s", u, err)    if u.Email != email {        t.Error("Expected email to be %s, found %v.", email, u.Email)    }}
查看完整描述

1 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

datastore.GetAll()不会将结果返回给您,因为该查询最终一致性适用。SDK 模拟最终一致性,不会立即返回新保存的实体。


但是在您TestCreateUser()使用的方法中datastore.Get(),即使实体是新保存的(“刚刚”),它也会返回给您,因为它是通过键查找,并且它们是高度一致的。


幕后发生的事情是,当您调用 时datastore.Put(),实体数据(属性的值)被保存,其键被索引,然后datastore.Put()返回,其他属性的索引和复合索引在“后台”异步更新。因此,如果您尝试执行使用索引来查找/列出实体的查询(您通过Email属性查询),则该查询将不会看到(不会包括)新实体,直到它们被正确索引。当您执行 a 时datastore.Get(),它通过键而不是其他(非键属性或复合)索引加载实体,因此通过键获取实体将“立即”(datastore.Put()返回后)看到新实体。


如果您想在本地环境中对此进行测试,您可以StronglyConsistentDatastore在创建将用于创建新上下文的实例时提供选项,如下所示:


inst, err := aetest.NewInstance(&aetest.Options{StronglyConsistentDatastore: true})

if err != nil {

    t.Fatalf("Failed to create instance: %v", err)

}

defer inst.Close()


req, err := inst.NewRequest("GET", "/", nil)

if err != nil {

    t.Fatalf("Failed to create req: %v", err)

}

ctx := appengine.NewContext(req)

另请注意,如果您使用 sleep(例如time.Sleep(time.Millisecond * 500)),datastore.GetAll()也将返回新实体,但上述选项是测试这一点的正确方法。


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 198 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号