doudou2121 2016-01-02 20:55 采纳率: 50%
浏览 159
已采纳

golang数据存储获取对象

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!

  • 写回答

2条回答 默认 最新

  • doushi8186 2016-01-02 22:26
    关注

    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).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面