使用Go语言在Google Appengine数据存储中更新实体。

huangapple go评论82阅读模式
英文:

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 = &amp; 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 &lt; len(participants) &amp;&amp; found == nil; i++ {
  if participants[i].Email == r.FormValue(&quot;email&quot;) {
    found = &amp;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 &#39;People&#39;
People := gaerecords.NewModel(&quot;People&quot;)

// create a new person
mat := People.New()
mat.
 SetString(&quot;name&quot;, &quot;Mat&quot;)
 SetInt64(&quot;age&quot;, 28)
 .Put()

// load person with ID 1
person, _ := People.Find(1)

// change some fields
person.SetInt64(&quot;age&quot;, 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(&quot;-age&quot;)

// use FindByQuery with a query object
oldestThreePeople, _ := People.FindByQuery(ageQuery)

// using events, make sure &#39;People&#39; records always get
// an &#39;updatedAt&#39; value set before being put (created and updated)
People.BeforePut.On(func(c *gaerecords.EventContext){
  person := c.Args[0].(*Record)
  person.SetTime(&quot;updatedAt&quot;, datastore.SecondsToTime(time.Seconds()))
})

huangapple
  • 本文由 发表于 2011年10月26日 22:46:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/7904402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定