【问题标题】:Is there any way to handle Google Datastore Kind Property names with spaces in Golang?有没有办法在 Golang 中处理带有空格的 Google Datastore Kind Property 名称?
【发布时间】:2016-05-05 15:54:49
【问题描述】:

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

我正在使用 Google Appengine Datastore 包将投影查询结果拉回 Appengine 内存中进行操作,这是通过将每个实体表示为 Struct 来完成的,每个 Struct 字段对应于一个属性名称,如下所示:

type Row struct {
Prop1    string
Prop2    int
}

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

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

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

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

干杯

【问题讨论】:

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


    【解决方案1】:

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

    例如:

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

    但是,如果您尝试使用包含空格的属性名称,datastore 包的 Go 实现会发生混乱。

    总结一下:你不能将有空格的属性名映射到 Go 中的结构字段(这是一个实现限制,将来可能会改变)。

    但好消息是您仍然可以加载这些实体,只是不能加载到结构值中。

    您可以将它们加载到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"
    

    请注意,您可以在结构上实现 datastore.PropertyLoadSaver 类型并在后台处理它,因此基本上您仍然可以将此类实体加载到结构值中,但您必须自己实现。

    但是争取实体名称和属性名称不要有空格。如果你允许这些,你会让你的生活变得更加艰难和悲惨。

    【讨论】:

    • 酷。感谢您让我了解 PropertyList 类型!你的回答比我的好很多。
    • 这是一个很好的答案,即使它没有给我我需要的东西。在这种情况下,我可能实际上会按照您对我的结构的建议进行操作,因为我 99% 都在使用我的应用程序,现在放弃将是一种耻辱 :) 干杯!
    【解决方案2】:

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

    我还要注意,属性名称成为每个实体和每个索引条目的一部分。我不知道 Google 是否会以某种方式压缩它们,但无论如何我都倾向于使用短属性名称。

    【讨论】:

    • 不幸的是,这不是一个解决方案,尽管它是明智的,因为我没有创建我正在使用的数据集。理想情况下,最好知道是否可以从属性名称 -> 结构字段定义某种映射,但 GAE 数据存储 API 似乎没有这样的东西。
    • 它确实有映射+索引设置。看我的回答。
    【解决方案3】:

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

    来自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"`
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-05
      • 2015-10-23
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      相关资源
      最近更新 更多