英文:
Updating entity in Google Appengine datastore with Go
问题
我正在玩GAE,Go和数据存储。我有以下结构:
type Coinflip struct {
Participants []*datastore.Key
Head string
Tail string
Done bool
}
type Participant struct {
Email string
Seen datastore.Time
}
(对于那些想知道的人,我将Participants
存储为Key
指针的切片,因为Go不会自动解引用实体。)
现在我想找到与已知的Coinflip
相关联的具有特定Email
地址的Participant
。像这样(这个是有效的):
coinflip,_:= find(key_as_string,context)
participants,_:= coinflip.fetchParticipants(context)/* Participant的切片*/
var found *Participant
for i:= 0; i < len(participants)&& found == nil; i ++ {
if participants [i] .Email == r.FormValue(“email”){
found = & participants [i]
}
}
(* found).Seen = datastore.SecondsToTime(time.Seconds())
我如何将*found
保存到数据存储中?显然我需要键,但Participant
结构和Key
之间的耦合非常松散。
我不确定如何继续。我需要从fetchParticipants
调用中返回键吗? Java和Python GAE实现似乎要简单得多(只需在对象上调用put()
)。
提前致谢,
英文:
I am toying with GAE, Go and the datastore. I have the following structs:
type Coinflip struct {
Participants []*datastore.Key
Head string
Tail string
Done bool
}
type Participant struct {
Email string
Seen datastore.Time
}
(For those wondering I store Participants
as a slice off Key
pointers because Go doesn't automatically dereferences entities.)
Now I want to find a Participant
with a particular Email
address associated with a know Coinflip
. Like so (this works):
coinflip, _ := find(key_as_string, context)
participants, _ := coinflip.fetchParticipants(context) /* a slice of Participant*/
var found *Participant
for i := 0; i < len(participants) && found == nil; i++ {
if participants[i].Email == r.FormValue("email") {
found = &participants[i]
}
}
(*found).Seen = datastore.SecondsToTime(time.Seconds())
How do I save *found
to the datastore? I need the key apparently but the coupling between the Participant
struct and the Key
is very loose.
I'm unsure how to proceed from here. Do I need to return the keys as well from the fetchParticipants
call? The Java and Python GAE implementation seem quite a bit simpler (just call put()
on the object).
Thanks in advance,
答案1
得分: 1
是的。然后调用"func Put(c appengine.Context, key *Key, src interface{}) (*Key, os.Error)"。
可能是一个公平的说法。Go社区对于"魔法"有很强的偏见。在这种情况下,Participant结构体有两个你声明的字段。在后台添加键会被认为是魔法。
英文:
> Do I need to return the keys as well from the fetchParticipants call?
Yes. And then call "func Put(c appengine.Context, key *Key, src interface{}) (*Key, os.Error)"
> The Java and Python GAE implementation seem quite a bit simpler (just
> call put() on the object).
Probably a fair statement. The Go community has a very strong bias against "magic". In this case the Participant struct has two fields that you have declared. Adding the key to it in the background would be considered magic.
答案2
得分: 0
要与Go
中的数据进行交互,可以考虑使用我们的新库https://github.com/matryer/gae-records,它是一个围绕数据存储的Active Record和数据对象封装。它可以为您解决很多麻烦。
例如,它支持以下操作:
// 创建一个名为'People'的新模型
People := gaerecords.NewModel("People")
// 创建一个新的人
mat := People.New()
mat.
SetString("name", "Mat")
SetInt64("age", 28)
.Put()
// 加载ID为1的人
person, _ := People.Find(1)
// 修改一些字段
person.SetInt64("age", 29).Put()
// 加载所有People
peeps, _ := People.FindAll()
// 删除mat
mat.Delete()
// 删除ID为2的用户
People.Delete(2)
// 通过传递一个func(*datastore.Query)给FindByQuery方法,找到前三个People
firstThree, _ := People.FindByQuery(func(q *datastore.Query){
q.Limit(3)
})
// 构建自己的查询并使用它
var ageQuery *datastore.Query = People.NewQuery().
Limit(3).Order("-age")
// 使用查询对象FindByQuery
oldestThreePeople, _ := People.FindByQuery(ageQuery)
// 使用事件,在放入(创建和更新)之前,确保'People'记录始终设置'updatedAt'值
People.BeforePut.On(func(c *gaerecords.EventContext){
person := c.Args[0].(*Record)
person.SetTime("updatedAt", datastore.SecondsToTime(time.Seconds()))
})
英文:
For interacting with data in Go
, consider using our new library https://github.com/matryer/gae-records for an Active Record, data objects wrapper around the datastore. It sorts out a lot of the hassle for you.
For example, it supports:
// create a new model for 'People'
People := gaerecords.NewModel("People")
// create a new person
mat := People.New()
mat.
SetString("name", "Mat")
SetInt64("age", 28)
.Put()
// load person with ID 1
person, _ := People.Find(1)
// change some fields
person.SetInt64("age", 29).Put()
// load all People
peeps, _ := People.FindAll()
// delete mat
mat.Delete()
// delete user with ID 2
People.Delete(2)
// find the first three People by passing a func(*datastore.Query)
// to the FindByQuery method
firstThree, _ := People.FindByQuery(func(q *datastore.Query){
q.Limit(3)
})
// build your own query and use that
var ageQuery *datastore.Query = People.NewQuery().
Limit(3).Order("-age")
// use FindByQuery with a query object
oldestThreePeople, _ := People.FindByQuery(ageQuery)
// using events, make sure 'People' records always get
// an 'updatedAt' value set before being put (created and updated)
People.BeforePut.On(func(c *gaerecords.EventContext){
person := c.Args[0].(*Record)
person.SetTime("updatedAt", datastore.SecondsToTime(time.Seconds()))
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论