有没有办法在Golang中处理带有空格的Google Datastore Kind Property名称?

时间:2016-05-05 15:54:50

标签: google-app-engine go data-structures struct google-cloud-datastore

我在数据存储中遇到了一个令人讨厌的问题,似乎没有任何解决方法。

我正在使用Google Appengine数据存储区将投影查询结果拉回到Appengine内存中进行操作,而这是通过将每个实体表示为Struct来完成的,每个Struct字段对应一个Property名称,如这样:

type Row struct {
Prop1    string
Prop2    int
}

这很好用,但我已将查询扩展到读取其他具有空格的属性名称。虽然查询运行正常,但它不能将数据拉回到结构中,因为它希望将给定值放入相同命名约定的结构中,并且我遇到了这种错误:

datastore: cannot load field "Viewed Registration Page" into a "main.Row": no such struct field

显然Golang不能代表像这样的结构域。有一个相关类型的字段,但没有明显的方法告诉查询将它放在那里。

这里最好的解决方案是什么?

干杯

3 个答案:

答案 0 :(得分:3)

实际上Go支持使用标签将实体属性名称映射到不同的结构字段名称(有关详细信息,请参阅此答案:What are the use(s) for tags in Go?)。

例如:

type Row struct {
    Prop1    string `datastore:"Prop1InDs"`
    Prop2    int    `datastore:"p2"`
}

但是如果你试图使用包含空格的属性名称,那么datastore包的Go实现会发生恐慌。

总结一下:你不能将具有空格的属性名称映射到Go 中的结构字段(这是一个可能在将来发生变化的实施限制)。

但好消息是你仍然可以加载这些实体,而不是加载到struct值中。

您可以将它们加载到datastore.PropertyList类型的变量中。 datastore.PropertyList基本上是datastore.Property的一个片段,其中Property是一个结构,它包含属性的名称,值和其他信息。

这是如何做到的:

k := datastore.NewKey(ctx, "YourEntityName", "", 1, nil) // Create the key
e := datastore.PropertyList{}

if err := datastore.Get(ctx, k, &e); err != nil {
    panic(err) // Handle error
}

// Now e holds your entity, let's list all its properties.
// PropertyList is a slice, so we can simply "range" over it:
for _, p := range e {
    ctx.Infof("Property %q = %q", p.Name, p.Value)
}

如果您的实体的商品"Have space"的值为"the_value",您会看到例如:

2016-05-05 18:33:47,372 INFO: Property "Have space" = "the_value"

请注意,你可以在你的struct上实现datastore.PropertyLoadSaver类型并在底层处理它,所以基本上你仍然可以将这些实体加载到struct值中,但你必须自己实现它。

但争取实体名称和属性名称没有空格。如果你允许这些,你将使你的生活更加艰难和悲惨。

答案 1 :(得分:0)

我所知道的所有编程语言都将空格视为变量/常量名称的结尾。显而易见的解决方案是避免在属性名称中使用空格。

我还要注意,属性名称成为每个实体和每个索引条目的一部分。我不知道谷歌是否以某种方式压缩它们,但我倾向于在任何情况下使用短的属性名称。

答案 2 :(得分:0)

您可以使用注释重命名属性。

来自docs

// A and B are renamed to a and b.
// A, C and J are not indexed.
// D's tag is equivalent to having no tag at all (E).
// I is ignored entirely by the datastore.
// J has tag information for both the datastore and json packages.
type TaggedStruct struct {
    A int `datastore:"a,noindex"`
    B int `datastore:"b"`
    C int `datastore:",noindex"`
    D int `datastore:""`
    E int
    I int `datastore:"-"`
    J int `datastore:",noindex" json:"j"`
}