如何在 Golang 中将 Key 放入 Struct ID 中的 Datastore?

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

Datastore - How to put Key inside Struct ID (golang)?

问题

我正在尝试构建一个多对多的关系,所以我有3个结构体:

type Orders struct {
  ID int64
  CustomerID string
  // 其他字段
}

type Products struct {
  ID int64
  Name string
  Description string
  // 其他字段
}

type OrderDetails struct {
  OrderID int64
  ProductID string
  Quantity int
}

我相信这是正确的方法,但我的问题是我不知道如何将数据存储键放入结构体的ID字段中,而不需要进行两次client.Put请求,因为据我所知,datastore.IncompleteKey("Products", nil)在放入之前不会返回新的键值。

我猜有些人会建议使用key *datastore.Key而不是ID int64,但我更喜欢将键转换为ID。

非常感谢任何帮助。

英文:

I'm trying to build a many to many relationship, so I have 3 structs:

type Orders struct {
  ID int64
  CustomerID string
  etc
}

type Products struct {
  ID int64
  Name string
  Description string
  etc
}

type OrderDetails struct {
  OrderID int64
  ProductID string
  Quantity int
}

I believe this is the right way to do it, but my problem now is that I do not know how to put the datastore key inside the struct ID without making two client.Put requests because as far as I can tell, datastore.IncompleteKey("Products", nil) will not return the new key value until after you put it..

I guess some people would recommend using key *datastore.Key instead of ID int64, but I would prefer to convert the key to an ID

Any help would be much appreciated

答案1

得分: 2

一种选择是提前分配键,你可以在调用Client.Put()之前在你的结构体中设置键。

你可以使用Client.AllocateIDs()来分配ID。你可以将一个不完整键的切片传递给它,然后你会得到一个完整的datastore.Key切片,数据存储会为你保留这些键(因此保证不会将其分配给其他人或在保存具有不完整键的实体时使用)。你可以通过Key.ID字段访问分配的键的数字ID。

但是将数字键ID存储在实体中是多余的,我认为这是一种浪费(资源)。每当你加载一个实体,例如使用Client.Get()加载一个实体,或者使用Client.GetAll()加载多个实体时,你也会得到键,并且你可以在结构体中“手动”填充数字ID作为后处理步骤。你还可以将这个后处理功能封装在一个函数中,每当你从数据存储中获取实体时,它会为你执行这个操作。

例如,如果你加载了一个包含OrderIDOrderDetails实体,你可以使用datastore.IDKey()来构造相应Order实体的datastore.Key。示例代码如下:

var orderDetails OrderDetails
// 加载 orderDetails

orderKey := datastore.IDKey("order", orderDetails.OrderID, nil)
// 现在你有了 Order 实体的键

var order Order
err := client.Get(ctx, orderKey, &order)

这意味着你不应该在实体中存储“自身ID”,如果已知数字ID,你可以构造datastore.Key值。

另请参阅相关问题:https://stackoverflow.com/questions/29567819/can-i-use-allocateids-as-string-datastore/29573089#29573089

英文:

One option is to allocate keys in advance, which you can set in your structs prior to calling Client.Put().

You can allocate IDs with the Client.AllocateIDs(). You can pass a slice of incomplete keys to it, and you get back a slice of complete datastore.Keys, which the datastore reserves for you (and thus guarantees not to "give out" to others or use when saving entities with incomplete keys). You can access the numeric IDs of the allocated keys in the Key.ID field.

But storing the numeric Key ID in the entities is redundant, and I find it a waste (of resources). Whenever you load an entity e.g. with Client.Get(), or multiple with Client.GetAll(), you also get back the keys, and you can fill the numeric IDs in the structs "manually" as a post-processing step. You can also wrap this post-processing functionality in a function which does this for you whenever you get entities from the datastore.

For example, if you have an OrderDetails entity loaded, which contains the OrderID, you may use datastore.IDKey() to construct the datastore.Key for the respective Order entity. Example doing it:

var orderDetails OrderDetails
// Load orderDetails

orderKey := datastore.IDKey("order", orderDetails.OrderID, nil)
// Now you have the key for the Order entity

var order Order
err := client.Get(ctx, orderKey, &order)

Which means you shouldn't store the "self ID" in the entities, you can construct datastore.Key values if the numeric ID is known.

Also see related question: https://stackoverflow.com/questions/29567819/can-i-use-allocateids-as-string-datastore/29573089#29573089

huangapple
  • 本文由 发表于 2017年3月25日 22:36:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/43017667.html
匿名

发表评论

匿名网友

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

确定