【问题标题】:Google App Engine Golang datastore.Query.GetAll not working locallyGoogle App Engine Golang datastore.Query.GetAll 无法在本地工作
【发布时间】:2014-08-01 00:15:11
【问题描述】:

我是 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 为 nil 很奇怪。

客户端正在连接到模拟 GAE 环境的 Python 服务器。有人可以帮忙吗?

【问题讨论】:

    标签: google-app-engine go


    【解决方案1】:

    我相信这是因为您正在执行跨组查询并且写入尚未应用于数据存储。开发服务器模拟类似于生产的写入可见性。当您不在事务或实体组中时,查询不会立即显示结果。

    来自文档,

    写操作在提交阶段之后立即返回,然后应用阶段异步进行。

    和,

    ... 当出现以下情况之一时,Apply 将前滚至完成 发生:

    定期数据存储扫描检查未完成的提交作业并应用 他们。某些操作(get、put、delete 和祖先查询) 使用受影响的实体组导致任何已被更改的 已提交但尚未申请在继续之前完成 新的操作。

    和,

    因为 Datastore 获取和祖先查询应用任何未完成的 执行前的修改,这些操作总是看到一个 以前所有成功交易的一致视图。这表示 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)
    }
    

    【讨论】:

    • 谢谢。这是有道理的。我在 GetAll 之前添加了一个经过时间,它可以工作。
    • 请注意,强制应用写入的 get 仅适用于 SDK。在现场环境中它不会那样工作。
    • @Greg 你能描述一下在哪些情况下这在实时环境中不起作用(或提供指针)?我很乐意用这些细节更新答案。到目前为止,我的有限测试(非失败条件)在本地应用程序和实时环境中都有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多