golang datastore获取对象

时间:2016-01-02 20:55:19

标签: google-app-engine go entity google-cloud-datastore

我是否需要一些指导我是否正确这样做。我试图得到一个汽车的单个物体。这就是我制作汽车的方式:

 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)

这是我试图再次开车的方式。

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
        }

但我收到错误:"错误获取汽车数据存储区:没有这样的实体"

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

谢谢!

2 个答案:

答案 0 :(得分:2)

您无法找到插入的实体,因为它是使用与您尝试获取的密钥不同的密钥保存的。

这一行:

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

使用新创建的不完整密钥保存Car实体。如果您尝试使用不完整的密钥保存实体,则数据存储区将为其分配(随机分布的)唯一数字ID 数字ID ,而不是string name

然后你尝试使用包含string name的密钥来获取它:

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

他们永远不会匹配!实体密钥的identifier部分可以是

  • 键名字符串
  • 或整数数字ID

但不是两者兼而有之。因此,当您保存实体时,其密钥要么具有string id,名为 name OR(异或),int64 id称为 intID 。< / p>

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

您的选择是:

予。 regnr作为字符串名称

使用regnr作为string name,如果您确实保证它是唯一的,并且它始终存在(没有{{1}没有要保存的实体}):

regnr

如果carKey := datastore.NewKey(context, "Car", req.Regnr, 0, nil) 不是空字符串,则是不完整的密钥,因此它将用作实体的req.Regnr string&# 39;关键。这意味着您可以通过以下方式获得此实体:

name

II。 carKey := datastore.NewKey(context, "Car", regnr, 0, nil) err := datastore.Get(context, carKey, &car) as&#34; normal&#34;属性

或者将regnr定义为&#34;正常&#34;具有不完整键的属性和保存实体,将唯一的数字ID分配留给系统。这不会限制您按regnr查找实体,因为如果它是索引属性,您可以通过它过滤实体。在此替代方案regnr不是实体密钥的一部分,因此您无法使用regnr来获取实体,您必须使用查询,例如datastore.Get()

比较

我的优点是它更紧凑,使用更少的数据存储空间,更快,更容易通过datastore.NewQuery()获取实体。

我的缺点是,您有责任保持regnr唯一,并且您无法regnr保存Car个实体(这可能是也可能不是问题)

答案 1 :(得分:0)

我注意到如果我通过将regnr作为键插入来创建汽车:

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)

我可以按照我在问题中写的那样找到它。但这是一个很好的方式吗?如果必要的话,我打算保持regnr的独特性。