Reputation: 1039
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
Upvotes: 3
Views: 1584
Reputation: 418645
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: Can I use AllocateIDs as "string" ? datastore
Upvotes: 2