Aniruddha Dwivedi
Aniruddha Dwivedi

Reputation: 91

Unable to retrieve entity from datastore created using IncompleteKey()

I am using "cloud.google.com/go/datastore" to store, update, retrieve entities from datastore. Struct created by me is -

type TExp struct {
    Key        string   `json:"key" datastore:"key,noindex"`
    Value      string   `json:"value" datastore:"value,noindex"`
} 

type service struct {
DataLayer *datastore.Client
}

When I create id for this using datastore.IncompleteKey("TExp", nil), I am able to create entity and can see it in real datastore.

func (s service)addTExp(ctx context.Context, request interface{}) (interface{}, error) {

req := request.(*TExp)
var tExp []TExp
var tExp2 TExp
tExp2.Key   = req.Key
tExp2.Value =   req.Value

query := datastore.NewQuery("TExp").Filter("key =", req.Key).Namespace("AdLive")
keys, err := s.DataLayer.GetAll(ctx, query, &tExp)
if err != nil {
    log.Errorf(ctx,"Error occurred while checking existence of key in kind")
}

if keys == nil {
log.Infof(ctx,"Keys: %v ", keys)
k := datastore.IncompleteKey("TExp", nil)
k.Namespace = "AdLive"
k.Kind = "TExp"

if _, err := s.DataLayer.Put(ctx, k, &tExp2); err != nil {
    return nil, marvin.NewJSONStatusResponse(
        "could not add TExp in DS",
        http.StatusBadRequest,
    )} 
   }
   return "OK",nil
}

Problem is before creating any entity, I want to ensure that any entity with same Key value doesn't exist in kind of that datastore already. To do this, first of all I am trying to check existence using GetAll method than if keys are nil, I want to call datastore.Put to add new entity. However, in each case(even for already present entities in Datastore), "keys" variable always get nil value.

keys, err := s.DataLayer.GetAll(ctx, query, &tExp)

Therefore, multiple entities get created with same key value in datastore. I am not able to find out how can I fix this issue in golang.

Note:- in datastore entities have structure

["Name/ID automatically generated by Datastore on calling IncompleteKey method", Key, Value].

Upvotes: 1

Views: 360

Answers (1)

Jim Morrison
Jim Morrison

Reputation: 2887

First, if you want to fetch a specific entity, you should use Get instead of GetAll, as Get is strongly consistent, and GetAll is not.

Second, since you are doing a Put with an incomplete key, your will never have a conflict on the new entity that you are only adding to your Datastore. It seems you want to be using a transaction to both Get & Put an entity with the complete key that is passed into your function.

Upvotes: 1

Related Questions