英文:
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作为后处理步骤。你还可以将这个后处理功能封装在一个函数中,每当你从数据存储中获取实体时,它会为你执行这个操作。
例如,如果你加载了一个包含OrderID
的OrderDetails
实体,你可以使用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.Key
s, 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论