无法将[] datastore.PropertyList传递给GetMulti函数(数据存储:src具有无效类型)

问题描述 投票:4回答:1

我写了以下函数,因为传递map是动态的我正在使用datastore.PropertyList。单个插入与PropertyList一起使用,但在Multiple中插入错误显示为“datastore:src具有无效类型”

编辑并添加了完整的源代码

哪里出错了?

package main

import (
"fmt"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
"google.golang.org/cloud"
"google.golang.org/cloud/datastore"
"io/ioutil"
)

func main() {
//Single Insert

// var map0 map[string]interface{}
// map0 = make(map[string]interface{})
// map0["Id"] = "600"
// map0["Name"] = "Prasad"
// map0["Age"] = 23

// setOneDataStore(map0)

//Multiple Insert

var allMaps []map[string]interface{}
allMaps = make([]map[string]interface{}, 2)

var map1 map[string]interface{}
map1 = make(map[string]interface{})
map1["Id"] = "700"
map1["Name"] = "Jay"
map1["Age"] = 23

var map2 map[string]interface{}
map2 = make(map[string]interface{})
map2["Id"] = "800"
map2["Name"] = "Peter"
map2["Age"] = 30

allMaps[0] = map1
allMaps[1] = map2

setManyDataStore(allMaps)
}

func getDataStoreClient() (client *datastore.Client, err error) {

keyFile := "JAYWORLD-30y4f7c347pq.json"
projectID := "jay-world"

jsonKey, err := ioutil.ReadFile(keyFile)
if err != nil {
    fmt.Println(err.Error())
} else {
    conf, err := google.JWTConfigFromJSON(
        jsonKey,
        datastore.ScopeDatastore,
        datastore.ScopeUserEmail,
    )
    if err != nil {
        fmt.Println(err.Error())
    } else {
        ctx := context.Background()
        client, err = datastore.NewClient(ctx, projectID, cloud.WithTokenSource(conf.TokenSource(ctx)))
        if err != nil {
            fmt.Println(err.Error())
        }
    }
}

return
}

func setManyDataStore(Objects []map[string]interface{}) {
ctx := context.Background()
client, err := getDataStoreClient() //have connection code in another function
ctx = datastore.WithNamespace(ctx, "CompanyA")

if err == nil {

    var keys []*datastore.Key
    keys = make([]*datastore.Key, len(Objects))
    var propArray []datastore.PropertyList
    propArray = make([]datastore.PropertyList, len(Objects))

    for index := 0; index < len(Objects); index++ {
        keys[index] = datastore.NewKey(ctx, "users", Objects[index]["Id"].(string), 0, nil)

        props := datastore.PropertyList{}

        for key, value := range Objects[index] {
            props = append(props, datastore.Property{Name: key, Value: value})
        }
        propArray[index] = props
    }

    if _, err := client.PutMulti(ctx, keys, propArray); err != nil {
        fmt.Println(err.Error())
    } else {
        fmt.Println("Success!")
    }

} else {
    fmt.Println("Connection Failed")
}
}

func setOneDataStore(Object map[string]interface{}) {

ctx := context.Background()
client, err := getDataStoreClient() //have connection code in another function
ctx = datastore.WithNamespace(ctx, "CompanyA")

key := datastore.NewKey(ctx, "users", Object["Id"].(string), 0, nil)

props := datastore.PropertyList{}

for key, value := range Object {
    props = append(props, datastore.Property{Name: key, Value: value})
}

_, err = client.Put(ctx, key, &props)
if err != nil {
    fmt.Println(err.Error())
} else {
    fmt.Println("Success!")
}
}
google-app-engine dictionary go google-cloud-datastore slice
1个回答
3
投票

由于错误表明:"datastore: src has invalid type"您传递的值为src&propArray)具有无效类型。

你不能传递*[]datastore.PropertyList类型的值作为srcClient.PutMulti()参数。引用文档:

src必须满足与dstGetMulti论证相同的条件。

dstClient.GetMulti()的条件:

dst必须是[]S[]*S[]I[]P,对于某些结构类型S,某些界面类型I,或一些非界面非指针类型P,使P*P实现PropertyLoadSaver。如果是[]I,每个元素必须是dst的有效Get:它必须是结构指针或实现PropertyLoadSaver

所以你不能将指针传递给切片,但是你可以并且你应该传递一个切片(删除地址&运算符):

if _, err := client.PutMulti(ctx, keys, propArray); err != nil {
    fmt.Println(err.Error())
} else {
    fmt.Println("Success!")
}

注意:看起来您正在创建具有特定ID的键(即index)。但是,如果密钥名称和id都是零值,则认为这是一个不完整的密钥。当你的index0开头时,你的第一把钥匙将是一把不完整的钥匙。您可能希望使用与索引不同的ID。

© www.soinside.com 2019 - 2024. All rights reserved.