Google app engine 云数据存储client.GetAll类型不匹配,但client.Get有效
我正在Google app engine 云数据存储client.GetAll类型不匹配,但client.Get有效,google-app-engine,go,google-cloud-datastore,Google App Engine,Go,Google Cloud Datastore,我正在appengine中编写一个go应用程序,它连接并从数据存储实体返回一些信息。我遇到一个问题,client.Get正在使用预定义的结构,但是client.GetAll正在抛出类型不匹配(反之亦然) 我将以下结构与这两种结构一起使用: type myStruct struct { ID int64 Field1 string Field2 string Release_Date time.Ti
appengine
中编写一个go
应用程序,它连接并从数据存储
实体返回一些信息。我遇到一个问题,client.Get
正在使用预定义的结构,但是client.GetAll
正在抛出类型不匹配(反之亦然)
我将以下结构与这两种结构一起使用:
type myStruct struct {
ID int64
Field1 string
Field2 string
Release_Date time.Time
}
当Release\u Date
定义为time.time
(如果int
,则失败):
当Release\u Date
定义为time.time
(如果int
)时,此操作失败:
错误:
数据存储:无法将字段“release\u date”加载到“myStruct”中:类型不匹配:int与time.time
(当我交换发布日期
定义时,反之亦然)
你知道怎么回事吗?这是个bug吗
其他信息:
我查看了实体仪表板,其中列出了数据类型为data/Time
,当我使用Get
检索实体时,它会很好地加载到结构中,我可以在代码中使用对象
我不知道为什么这不起作用。所以这不是一个优雅的解决方案,但对我来说是有效的 我认为原因是我创建的第一个实体有一个类型为
int
的字段Release\u Date
,但后来我使用类型Date/Time
添加了实体。在测试过程中,我删除了int
类型为Release\u Date
的实体,因此剩下的实体只有Date/Time
。尽管没有Release\u Date
类型为int
的实体,但我的代码在服务器端失败。它一直希望该字段的类型为int
我的理论是,实体定义是在我第一次创建实体时建立的,并且在以后更改数据类型时没有更新,即使没有实体仍然使用typeint
因此,我最终做的是备份我的实体,删除所有实体,然后在Release\u Date
字段中重新添加只有Date/Time
的实体。一旦我这么做了,一切都很顺利。我仍然具有与上面所示相同的大小写(即我的Struct
使用字段
,但我的查询使用字段
)
这可能是一件容易复制的事情,但我还没来得及去做。如果其他人有时间进行测试,请添加评论,否则我将最终提交一份bug报告。您确定每个记录都有一个发布日期,即时间。时间?这似乎是最有可能的原因-实际上有一条(或多条)记录带有该字段的int,并且实际上有一些记录带有time.time,因此无论您选择哪一条,当您执行
GetAll
时,它都会失败,因为它会找到至少一条不匹配的记录。我检查了(我现在只测试了三个实体)再仔细检查一下。它们都是相同的数据类型。这里没有足够的信息提供帮助——看起来@dave对实体的描述是正确的,不是所有实体都以相同的方式存储,或者可能有两种不同的实体类型。在Get
示例中,我们看不到如何创建密钥(k
),因此我们不知道这是否使用了与GetAll
示例相同的“myEntityType”
。尽管如此,从您的错误消息中我们知道,您已经将一些实体的发布日期存储为int
,一些存储为time.time
。此外,我还从未见过NewQuery
、Project
或Order
以及小写参数,因为它们只适用于导出的类型和字段。我不确定数据存储包是否只是不区分大小写地对待它们(因为这些只是引用您已经存储的东西的字符串参数,这是完全可能的),但在我看来,这是不寻常的,不协调的。我在创建k
的地方添加了这些参数。我还取消了数据存储中的所有条目,并添加了一个条目(有趣的是,这意味着您必须重建索引)对数据类型进行三重检查。您引用的参数是我的数据存储中的命名字段,因此它们应该匹配大小写,不是吗?
k := db.datastoreKey(id)
myStruct := &myStruct{}
if err := db.client.Get(ctx, k, myStruct ); err != nil {
return nil, fmt.Errorf("datastore: %v", err)
}
func (db *datastoreDB) datastoreKey(id int64) *datastore.Key {
return datastore.IDKey("myEntityType", id, nil)
}
var myStructs []*myStruct
q := datastore.NewQuery("myEntityType").
Project("field1", "field2", "release_date").
Order("field1")
keys, err := db.client.GetAll(ctx, q, &myStructs)
if err != nil {
return nil, fmt.Errorf("datastore: %v", err)
}