google-app-engine - 如何从数据存储中获取 ID 以更新实体?

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

我正在构建一个 REST API 来执行 CRUD 操作,

我有一个 Go 结构体:

type VisitEntiry struct {
    FirstName string `json:"firstname"`
    LastName string `json:"lastname"`
    UserName string `json:"username"`
    PassWord string `json:"password"`
    Email string `json:"email"`
}

我能够在数据存储中保存和检索 VisitEntiries。所以我需要编辑访问实体,我想获取数据存储分配给 VisitEntiry 使用的 ID。我验证了 ID 是使用 Google 的数据存储仪表板分配的,但是如何从检索到的 VisitEntiry 中获取 ID?

云你请帮我写代码来编辑实体。

import (
    "encoding/json"
    "log"
    "net/http"
    "golang.org/x/net/context"
    "google.golang.org/appengine"
    "google.golang.org/appengine/datastore"
)

const KINDNAME = "Vist"

const NAMESPACENAME = "-Test-"

type VisitEntiry struct {
    FirstName string `json:"firstname"`
    LastName string `json:"lastname"`
    UserName string `json:"username"`
    PassWord string `json:"password"`
    Email string `json:"email"`
}
var visit *VisitEntiry
//SuccessResponse store response
type SuccessResponse struct {
    //  visit VisitEntiry `json:"entity"`
    ID int64 `json:"Id"`
    Message string `json:"message"`
}
func init() {
    http.HandleFunc("/api/getallvisits", restHandler)
    http.HandleFunc("/api/postavisit", restHandler)
}
func restHandler(w http.ResponseWriter, r *http.Request) {
    var v VisitEntiry
    _ = json.NewDecoder(r.Body).Decode(&v)
    json.NewEncoder(w).Encode(v)
    visit = &VisitEntiry{
        FirstName: v.FirstName,
        LastName: v.LastName,
        UserName: v.UserName,
        PassWord: v.PassWord,
        Email: v.Email,
    }
    switch r.Method {
    case "GET":
        getallvisitshandler(w, r)
        return
    case "POST":
        putavisthandler(w, r)
        return
    case "DELETE":
        //  handleDelete(ed, w, r)
        return
    default:
        //respondErr(w, r, http.StatusNotFound, "is not supported HTTP methods")
    }
}
func respond(w http.ResponseWriter, r *http.Request, status int, data interface{}) {
    w.WriteHeader(status)
    if data != nil {
        json.NewEncoder(w).Encode(data)
    }
}
func getallvisitshandler(w http.ResponseWriter, r *http.Request) {

    var visitslist []VisitEntiry
    var ctx context.Context
    ctx = appengine.NewContext(r)
    ctx, err := appengine.Namespace(ctx, NAMESPACENAME)
    if err != nil {
        return
    }
    q := datastore.NewQuery(KINDNAME)
    _, err = q.GetAll(ctx, &visitslist)
    json.NewEncoder(w).Encode(visitslist)
    //log.Printf("%#v Getting values From Datastore - visits ", visitskeys)
}
func putavisthandler(w http.ResponseWriter, r *http.Request) {
    var ctx context.Context
    keys := make([]*datastore.Key, 1)
    ctx = appengine.NewContext(r)
    ctx, err := appengine.Namespace(ctx, NAMESPACENAME)
    if err != nil {
        return
    }
    keys[0] = datastore.NewIncompleteKey(ctx, KINDNAME, nil)
    visitentity, err := datastore.Put(ctx, keys[0], visit)
    ID := visitentity.IntID()
    value := visitentity.Encode()
    //value : = visitentity.Encode()
    log.Printf("%#v Getting values From Datastore - visits ", value)
    respond(w, r, http.StatusOK, SuccessResponse{ID, "Visit Entity Inserted Successfully! "})
}

最佳答案

在保存时获取实体的 key

当您将新实体放入数据存储区时,例如与 datastore.Put()函数,您将获得分配的 key 作为返回:

func Put(c context.Context, key *Key, src interface{}) (*Key, error)

更新现有实体

要更新数据存储中的现有实体,您首先需要从数据存储中获取它。

这可能发生在已经知道它的 key ,并使用datastore.Get() 得到它。 .在这种情况下,您显然已经有了 key 。

您还可以通过运行查询来更新实体。在这种情况下,最终您将通过执行 Query.GetAll() 来获取实体。方法。 Query.GetAll() 返回它返回的实体的键:

func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error)

例如,如果查询返回 10 个实体(将存储在 dst 中),它还将返回 10 个对应的键作为返回实体的 slice 。所以你也有你的 key 。

另一种选择是使用查询迭代器,由 Query.Run() 获得.在这种情况下,您将通过调用 Iterator.Next() 获得实际实体。再次返回 key :

func (t *Iterator) Next(dst interface{}) (*Key, error)

传输实体 key

客户端要更新一个实体,它必须有一些唯一标识该实体的信息,方便的是它的键。所以当客户端请求实体时,服务器也应该发送它的 key 。当客户端想要更新实体时,它必须连同更新的数据一起发送 key 。因此服务器将能够更新由 key 表示的正确实体。

要向客户端发送 key ,您可以使用 Key.Encode()将 key 编码为网络安全字符串的方法。

客户端应发回相同的 key 字符串。

并且服务器可能使用datastore.DecodeKey()函数将 key 字符串转回 *datastore.Key值(value)。

注意:如果您使用的是数字 ID 并且知道类型,则可以选择仅传输数字 ID。您可以使用 Key.IntID() 获取数字 ID方法。你可以使用 datastore.NewKey()在服务器端从数字 ID 构造 key ,如下所示:

numericID = int64(0) // Get this from the request
key := datastore.NewKey(ctx, KINDNAME, "", numericID, nil)

查看有关键的答案:Can I use AllocateIDs as "string" ? datastore

关于google-app-engine - 如何从数据存储中获取 ID 以更新实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47576286/

相关文章:

google-app-engine - Google App Engine 超时?

for-loop - Golang 一行for循环

python - 使用 ndb 模型使用 google app engine 进行全文搜索

java - Google Datastore 查询返回陈旧数据

python - 创建拼写检查,需要在App Engine中访问words.txt

django - 使用 Gearman 模拟 Google Appengine 的任务队列

go - 无法运行 go 权限被拒绝?

python - 如何在 GAE Python NDB 中获取最新数据

python - GAE 管理的虚拟机 : Possible to use C-based Python libraries with standard runtime?

logging - 在 golang 中将 panic 输出重定向到带有时间戳的文件