获取 Golang Datastore 对象

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

golang datastore get object

问题

我需要一些指导,看我是否做得正确。我试图获取一辆汽车的单个对象。这是我创建汽车的方式:

car := &types.Car{
    Model:        req.Model,
    Regnr:        req.Regnr,
    Year:         req.Year,
    Type:         req.Type,
    CreationTime: time.Now(),
    Sold:         false,
}
_, err := datastore.Put(context, datastore.NewIncompleteKey(context, "Car", nil), car)

这是我尝试再次获取汽车的方式:

vars := mux.Vars(r)
regnr := vars["regnr"]
car := types.Car{}
carKey := datastore.NewKey(context, "Car", regnr, 0, nil)
err := datastore.Get(context, carKey, &car)
if err != nil {
    log.Println("error getting car", err)
    w.WriteHeader(http.StatusInternalServerError)
    return
}

但是我得到了错误信息:"error getting car datastore: no such entity"。

我知道我可以使用GetAll并限制为一个结果。但是如果我要删除一个对象,我需要该实体。我想做对的。

谢谢!

英文:

I need some guidance whether I am doing this correct. Im trying to get a single object of a car. This is how I create a car:

 car := &types.Car{
			Model:        req.Model,
			Regnr:        req.Regnr,
			Year:         req.Year,
			Type:         req.Type,
			CreationTime: time.Now(),
			Sold:         false,
		}
		//key := datastore.NewKey(context, "Car", "", 0, nil)

		_, err := datastore.Put(context, datastore.NewIncompleteKey(context, "Car", nil), car)

This is the way im trying to get the car again.

vars := mux.Vars(r)
		regnr := vars["regnr"]
		car := types.Car{}
		carKey := datastore.NewKey(context, "Car", regnr, 0, nil)
		err := datastore.Get(context, carKey, &car)
		if err != nil {
			log.Println("error getting car", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

But I get the error: "error getting car datastore: no such entity"

I know I can do a GetAll and limit to one. But if im deleting an object, I need the entity. I guess. So I want to do it right.

Thanks!

答案1

得分: 2

你无法找到插入的实体,因为它保存时使用的键与你尝试获取它的键不同。

这行代码:

_, err := datastore.Put(context, datastore.NewIncompleteKey(context, "Car", nil), car)

使用新创建的不完整键保存了一个Car实体。如果你尝试使用不完整的键保存实体,数据存储将为其分配一个(随机分布的)唯一的数值ID,而不是字符串名称。

然后你尝试使用一个具有字符串名称的键来获取它:

carKey := datastore.NewKey(context, "Car", regnr, 0, nil)

它们永远不会匹配!实体键的标识符部分可以是以下之一:

  • 键名称字符串
  • 或者整数数值ID

但不能同时存在。因此,当你保存一个实体时,它的键要么具有名为"name"的字符串ID,要么(异或)具有名为"intID"的int64 ID。

请阅读我关于实体标识符的答案:Can I use AllocateIDs as "string"?

你有以下选项:

I. regnr 作为字符串名称

如果你确保regnr是唯一的,并且它始终存在(没有没有regnr的实体需要保存),则可以将regnr作为字符串名称使用:

carKey := datastore.NewKey(context, "Car", req.Regnr, 0, nil)

如果req.Regnr不是空字符串,则这不是一个不完整的键,因此它将用作实体键的字符串名称。这意味着以后你可以通过以下方式获取该实体:

carKey := datastore.NewKey(context, "Car", regnr, 0, nil)
err := datastore.Get(context, carKey, &car)

II. regnr 作为“普通”属性

或者将regnr定义为“普通”属性,并使用不完整的键保存实体,将唯一的数值ID分配给系统。如果regnr是一个索引属性,这不会限制你通过regnr筛选实体。在这种替代方案中,regnr不是实体键的一部分,因此你不能使用datastore.Get()获取实体,而必须使用查询,例如datastore.NewQuery()

比较:

I. 的优点是它更紧凑,使用的数据存储空间更少,通过regnr更快且更容易获取实体。

I. 的缺点是你需要确保regnr是唯一的,并且不能保存没有regnrCar实体(这可能是一个问题或不是问题)。

英文:

You can't find the inserted entity, because it was saved with a different key than the one you try to get it by.

This line:

_, err := datastore.Put(context, datastore.NewIncompleteKey(context, "Car", nil), car)

Saves a Car entity with a newly created, incomplete key. If you try to save an entity with an incomplete key, the datastore will assign a (randomly distributed) unique numeric ID to it. A numeric ID, not a string name.

And then you try to get it with a key having a string name:

carKey := datastore.NewKey(context, "Car", regnr, 0, nil)

They will never match! The identifier part of an entity's key can either be

  • a key name string
  • or an integer numeric ID

But not both. So when you save an entity, its key either has a string id called name OR (exclusive OR) an int64 id called intID.

Please do read my answer about entity identifiers: Can I use AllocateIDs as “string” ?

Your options are:

I. regnr as string name

Either use regnr as a string name if you do have guarantee it's unique, and it is always present (no entity to be saved without regnr):

carKey := datastore.NewKey(context, "Car", req.Regnr, 0, nil)

This is not an incomplete key if req.Regnr is not an empty string, and thus it will be used as the string name of the entity's key. Which means later you can get this entity by:

carKey := datastore.NewKey(context, "Car", regnr, 0, nil)
err := datastore.Get(context, carKey, &car)

II. regnr as "normal" property

Or define regnr as a "normal" property and save entities with an incomplete key, leaving the unique numeric ID assignment to the system. This won't limit you in finding entities by regnr as you can filter entities by it if it's an indexed property. In this alternative regnr is not part of the entity's key, so you can't use datastore.Get() to get an entity, you have to use a query, e.g. datastore.NewQuery().

Comparision:

Pros of I. are that it's more compact, uses less datastore space, faster and easier to get entities by regnr.

Cons of I. are that you are responsible keeping regnr unique, and you can't save Car entities without regnr (which may or may not be a problem).

答案2

得分: 0

我注意到,如果我像这样将regnr作为键创建一个汽车:

car := &types.Car{
    Model:        req.Model,
    Regnr:        req.Regnr,
    Year:         req.Year,
    Type:         req.Type,
    CreationTime: time.Now(),
    Sold:         false,
}
carKey := datastore.NewKey(context, "Car", req.Regnr, 0, nil)
_, err := datastore.Put(context, carKey, car)

我可以通过在问题中所写的方式找到它。但这样做好吗?如果有必要,我计划保持regnr的唯一性。

英文:

I noticed that if I create a car by inserting the regnr as key like this:

car := &types.Car{
			Model:        req.Model,
			Regnr:        req.Regnr,
			Year:         req.Year,
			Type:         req.Type,
			CreationTime: time.Now(),
			Sold:         false,
		}
		//key := datastore.NewKey(context, "Car", "", 0, nil)
		carKey := datastore.NewKey(context, "Car", req.Regnr, 0, nil)
		_, err := datastore.Put(context, carKey, car)

I can find it by doing as I wrote in the question. But is this a good way of doing it? I plan on keeping the regnr unique anyway if it is neccesary.

huangapple
  • 本文由 发表于 2016年1月3日 04:55:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/34570633.html
匿名

发表评论

匿名网友

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

确定