无法将Protobuf解组为types.Struct类型。

huangapple go评论104阅读模式
英文:

Unable to Unmarshall to types.Struct with Protobuf

问题

我正在处理一个旧版的Go应用程序,类型定义方面让我抓狂。

在某个时候,我需要返回一个值,该值的类型是types.Struct(来自github.com/gogo/protobuf/types)。

以下是该函数的签名:

  1. GetDeviceConfig(ctx context.Context, in *DeviceID, opts ...grpc.CallOption) (*types.Struct, error)

我从Postgres数据库(使用GORM)中获取值,使用一个名为"config"的字符串列。它可以是任何类型的JSON。

这只是一个示例:

  1. {"fields":{"A":{"Kind":{"string_value":"B"}},"C":{"Kind":{"string_value":"D"}}}}

当我尝试将其解组为map[string]interface{}时,它完美运行:

  1. err := client.DB.Where("id = ?", id, 0).First(&device).Error
  2. if err != nil && err != gorm.ErrRecordNotFound {
  3. return nil, err
  4. }
  5. var dat map[string]interface{}
  6. if err := json.Unmarshal([]byte(device.Config), &dat); err != nil {
  7. panic(err)
  8. }

但是我需要将其转换为types.Struct(有效的protobuf签名,不能更改)。我最好的猜测是这样的:

  1. // 将JSON转换为结构体
  2. s := types.Struct{}
  3. if err := json.Unmarshal([]byte(device.Config), &s); err != nil {
  4. panic(err)
  5. }
  6. // fmt.Println(s)

但是s是空的,没有填充任何数据。

需要帮助吗?

英文:

I am working on a legacy Go app that it's driving me crazy in terms of type definition.

At some point I need to return a value with the value types.Struct (from github.com/gogo/protobuf/types).

Here is the signature for the function:

  1. GetDeviceConfig(ctx context.Context, in *DeviceID, opts ...grpc.CallOption) (*types.Struct, error)

I'm getting the value from a Postgres database (with GORM) using a string column called "config". It could be any type of JSON.

Just an example:

  1. {"fields":{"A":{"Kind":{"string_value":"B"}},"C":{"Kind":{"string_value":"D"}}}}

When I try to unmarshall to a map[string]interface{} it works like a charm:

  1. err := client.DB.Where("id = ?", id, 0).First(&device).Error
  2. if err != nil && err != gorm.ErrRecordNotFound {
  3. return nil, err
  4. }
  5. var dat map[string]interface{}
  6. if err := json.Unmarshal([]byte(device.Config), &dat); err != nil {
  7. panic(err)
  8. }

but I need to conver it to types.Struct (valid protobuf signature that cannot be changed). My best guess was something like this:

  1. // convert json to struct
  2. s := types.Struct{}
  3. if err := json.Unmarshal([]byte(device.Config), &s); err != nil {
  4. panic(err)
  5. }
  6. // fmt.Println(s)

but s is empty. No data is populated.

Any help?

答案1

得分: 1

为了将JSON解组为Struct,你需要使用Unmarshaler,它位于jsonpb包中。以下是一个示例代码:

  1. err := jsonpb.UnmarshalString(device.Config, &s)
  2. [...]

你可以在jsonpb_test.go中找到更多示例。

英文:

In order to unmarshal JSON into a Struct, you need to use Unmarshaler found in the jsonpb package. Something along the following lines should work:

  1. err := jsonpb.UnmarshalString(device.Config, &s)
  2. [...]

You can find further examples in jsonpb_test.go.

huangapple
  • 本文由 发表于 2021年11月3日 02:57:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/69815643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定