2017-09-26 211 views
0

我正在学习golang和谷歌应用程序引擎数据存储。无法存储在数据存储gcloud

我打算做一个简单的休息API调用来保存和检索数据存储中的数据。

我遵循了几个你好世界教程和官方入门指南。最后我想到的是这个。

`

package hello 

import (
     "fmt" 
     "log" 
     "net/http" 
     "encoding/json" 
     "cloud.google.com/go/datastore" 
     "golang.org/x/net/context" 
     "github.com/gorilla/mux" 
     "time" 
) 
type Task struct { 
     Description string `datastore:"description"` 
     Created time.Time `datastore:"created"` 
     id  int64 
} 
func saveData(w http.ResponseWriter, r *http.Request){ 
     fmt.Println("Endpoint Hit: saveData") 
     input := r.URL.Query().Get("input") 
     fmt.Println(input) 

     ctx := context.Background() 
     projectID := "api-project-426361742627" 
     client, err := datastore.NewClient(ctx, projectID) 
     if err != nil { 
       log.Fatalf("Failed to create client: %v", err) 
     } 
     kind := "Task" 
     task := Task{ 
       Description: input, 
       Created: time.Now(), 
     } 
     taskKey := datastore.IncompleteKey(kind, nil) 

     if _, err := client.Put(ctx, taskKey, &task); err != nil { 
       log.Fatalf("Failed to save task: %v", err) 
     } 

     fmt.Printf("Saved %v: %v\n", taskKey, task.Description) 
     json.NewEncoder(w).Encode(task) 
} 
func returnAll(w http.ResponseWriter, r *http.Request){ 
     fmt.Println("Endpoint Hit: returnAll") 

     ctx := context.Background() 
     projectID := "api-project-426361742627" 
     client, err := datastore.NewClient(ctx, projectID) 
     if err != nil { 
       log.Fatalf("Failed to create client: %v", err) 
     } 

     query := datastore.NewQuery("Task").Order("description") 

     var tasks []*Task 

     keys, err := client.GetAll(ctx, query, &tasks) 
     for i, key := range keys { 
       tasks[i].id = key.ID 
     } 
     // for _, t := range tasks { 
     //   // fmt.Println(t.id, t.Description) 
     // } 

     json.NewEncoder(w).Encode(tasks) 
} 

func homePage(w http.ResponseWriter, r *http.Request){ 
     fmt.Fprintf(w, "Welcome to the HomePage!") 
     fmt.Println("Endpoint Hit: homePage") 
} 
func handleRequests() { 
     myRouter := mux.NewRouter() 
     myRouter.HandleFunc("/", homePage) 
     myRouter.HandleFunc("/save", saveData) 
     myRouter.HandleFunc("/retrieve", returnAll) 
     http.Handle("/", myRouter) 
} 
func init() { 
     handleRequests() 
} 

`

现在我面临的问题是在这条线

client, err := datastore.NewClient(ctx, projectID)

我收到以下错误。

2017/09/26 07:15:16 http: panic serving 127.0.0.1:59488: not an App Engine context 
goroutine 17 [running]: 
net/http.(*conn).serve.func1(0xc82021e000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:1389 +0xc1 
panic(0xa44740, 0xc82018a8c0) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/runtime/panic.go:443 +0x4e9 
google.golang.org/appengine/internal.fullyQualifiedAppID(0x7f4142e12be0, 0xc82000b4e0, 0x0, 0x0) 
    /home/aditya/work/src/google.golang.org/appengine/internal/identity_classic.go:54 +0x8b 
google.golang.org/appengine/internal.FullyQualifiedAppID(0x7f4142e12be0, 0xc82000b4e0, 0x0, 0x0) 
    /home/aditya/work/src/google.golang.org/appengine/internal/api_common.go:77 +0xe2 
google.golang.org/appengine/internal.AppID(0x7f4142e12be0, 0xc82000b4e0, 0x0, 0x0) 
    /home/aditya/work/src/google.golang.org/appengine/internal/identity.go:13 +0x37 
google.golang.org/appengine.AppID(0x7f4142e12be0, 0xc82000b4e0, 0x0, 0x0) 
    /home/aditya/work/src/google.golang.org/appengine/identity.go:20 +0x37 
golang.org/x/oauth2/google.FindDefaultCredentials(0x7f4142e12be0, 0xc82000b4e0, 0xc820222170, 0x1, 0x1, 0xc820222150, 0x0, 0x0) 
    /home/aditya/work/src/golang.org/x/oauth2/google/default.go:92 +0x5a8 
google.golang.org/api/internal.Creds(0x7f4142e12be0, 0xc82000b4e0, 0xc820248240, 0xc8202452c0, 0x0, 0x0) 
    /home/aditya/work/src/google.golang.org/api/internal/creds.go:37 +0x173 
google.golang.org/api/transport/grpc.Dial(0x7f4142e12be0, 0xc82000b4e0, 0xc820245638, 0x3, 0x3, 0x0, 0x0, 0x0) 
    /home/aditya/work/src/google.golang.org/api/transport/grpc/dial.go:47 +0x272 
cloud.google.com/go/datastore.NewClient(0x7f4142e12be0, 0xc82000b4e0, 0xc0c320, 0x18, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0) 
    /home/aditya/work/src/cloud.google.com/go/datastore/datastore.go:87 +0x87f 
main76346.returnAll(0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    hello.go:51 +0x1b8 
net/http.HandlerFunc.ServeHTTP(0xcd13d8, 0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:1618 +0x3a 
github.com/gorilla/mux.(*Router).ServeHTTP(0xc820052660, 0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    /home/aditya/work/src/github.com/gorilla/mux/mux.go:133 +0x37c 
net/http.(*ServeMux).ServeHTTP(0xc82000eab0, 0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:1910 +0x17d 
appengine_internal.handleFilteredHTTP(0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/appengine_internal/api_dev.go:102 +0x409 
net/http.HandlerFunc.ServeHTTP(0xccfe48, 0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:1618 +0x3a 
net/http.serverHandler.ServeHTTP(0xc820078500, 0x7f4142dcb058, 0xc820234000, 0xc82022a000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:2081 +0x19e 
net/http.(*conn).serve(0xc82021e000) 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:1472 +0xf2e 
created by net/http.(*Server).Serve 
    /home/aditya/google-cloud-sdk/platform/google_appengine/goroot-1.6/src/net/http/server.go:2137 +0x44e 
INFO  2017-09-26 07:15:16,800 module.py:821] default: "GET /retrieve HTTP/1.1" 500 3349 

我不知道如何去解决这个问题。我尝试使用

gcloud auth application-default login 

给本地访问数据存储,但它不工作。每当我尝试保存数据或在初始化数据存储新客户端时返回所有条目,我都面临着这个问题。

回答

2

更新您的处理器使用的应用程序的处理请求,而不是context.Background()

func saveData(w http.ResponseWriter, r *http.Request){ 
    // .. 
    fmt.Println(input) 

    ctx := appengine.NewContext(r) 
    projectID := "api-project-426361742627" 
    // ... 
} 

记住这方面一个导出的上下文可以作为一个不透明的价值容器以及与App Engine环境大量使用此功能。

appengine docs

+0

感谢它的工作。 –