英文:
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
是唯一的,并且不能保存没有regnr
的Car
实体(这可能是一个问题或不是问题)。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论