golang 数据存储获取对象

golang datastore get object

我需要一些指导是否正确。我正在尝试获取汽车的单个对象。这就是我创建汽车的方式:

 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
        }

但我收到错误:"error getting car datastore: no such entity"

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

谢谢!

我注意到如果我通过像这样插入 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 的唯一性。

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

这一行:

_, 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

但不是两者。因此,当您保存一个实体时,它的键要么有一个名为 namestring id,要么(异或)一个名为 intID[ 的 int64 id.

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

您的选择是:

我。 regnr 作为字符串名称

使用 regnr 作为 string name 如果你能保证它是独一无二的,并且它总是存在(没有 regnr 就没有实体可以保存) :

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

如果 req.Regnr 不是空字符串,这 不是 一个不完整的密钥,因此它将被用作 string name 实体的密钥。这意味着稍后您可以通过以下方式获得此实体:

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

二. regnr 作为 "normal" 属性

或将regnr定义为"normal"属性并使用不完整的键保存实体,将唯一的数字ID分配给系统。这不会限制您按 regnr 查找实体,因为如果它是索引 属性,您可以按它过滤实体。在这个替代方案中 regnr 不是实体键的一部分,所以你不能使用 datastore.Get() 来获取实体,你必须使用查询,例如datastore.NewQuery().

比较:

I. 的优点是它更紧凑,使用更少的数据存储 space,通过 regnr.

更快更容易地获取实体

I. 的缺点是您有责任保持 regnr 的唯一性,并且您无法在没有 regnr 的情况下保存 Car 个实体(这可能是也可能不是问题) .