使用 Go 更新 Google Appengine 数据存储区中的实体

发布于 2024-12-12 04:39:02 字数 1296 浏览 0 评论 0原文

我正在摆弄 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 关联的特定电子邮件地址的 code>参与者。像这样(这有效):

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())

如何将 *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,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海不蓝 2024-12-19 04:39:02

我是否还需要从 fetchParticipants 调用中返回密钥?

是的。然后调用“func Put(c appengine.Context, key *Key, src interface{}) (*Key, os.Error)”

Java 和 Python GAE 实现看起来相当简单(只是
对对象调用 put())。

也许是一个公平的说法。 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.

一绘本一梦想 2024-12-19 04:39:02

要与 Go 中的数据进行交互,请考虑使用我们的新库 https://github。 com/matryer/gae-records 用于 Active Record,数据存储周围的数据对象包装器。可以为你解决很多麻烦。

例如,它支持:

// 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()))
})

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()))
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文