【问题标题】:SQLC - how to retrieve data stored as JSONBSQLC - 如何检索存储为 JSONB 的数据
【发布时间】:2022-11-02 14:38:00
【问题描述】:

我有一个包含 JSONB 字段的简单表:

CREATE TABLE IF NOT EXISTS "test_table" (
    "id" text NOT NULL,
    "user_id" text NOT NULL,
    "content" jsonb NOT NULL,
    "create_time" timestamptz NOT NULL,
    "update_time" timestamptz NOT NULL,
    PRIMARY KEY ("id")
);

我使用一个简单的查询来生成带有 SQLC 的样板。

-- name: GetTestData :one
SELECT * FROM test_table
WHERE id = $1 LIMIT 1;

但是content 属性生成为json.RawMessage

type TestTable struct {
    ID          string          `json:"id"`
    UserId      string          `json:"user_id"`
    Content     json.RawMessage `json:"content"`
    CreateTime  time.Time       `json:"create_time"`
    UpdateTime  time.Time       `json:"update_time"`
}

这是存储在内容列中的 JSON 示例:

{
  "static": {
    "product": [
      {
        "id": "string",
        "elements": {
          "texts": [
            {
              "id": "string",
              "value": "string"
            }
          ],
          "colors": [
            {
              "id": "string",
              "value": "string"
            }
          ],
          "images": [
            {
              "id": "string",
              "values": [
                {
                  "id": "string",
                  "value": "string"
                }
              ]
            }
          ]
        }
      }
    ]
  },
  "dynamic": {
    "banner": [
      {
        "id": "string",
        "elements": {
          "texts": [
            {
              "id": "string",
              "value": "string"
            }
          ],
          "colors": [
            {
              "id": "string",
              "value": "string"
            }
          ],
          "images": [
            {
              "id": "string",
              "values": [
                {
                  "id": "string",
                  "value": "string"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

静态或动态内的嵌套属性是数组。

content 属性应该包含一个嵌套对象,我似乎无法提取其中的数据。 json.Unrmarshall() 似乎只获得顶级属性。有没有办法投 map[string]interface{} 内容或帮助 SQLC 将属性生成为接口而不是 RawMessage?

我试图解决这个问题,只是像这样解组原始消息:

var res map[string]json.RawMessage
if err := json.Unmarshal(testingData.Content, &res); err != nil {
    return nil, status.Errorf(codes.Internal, "Serving data err %s", err)
}

var static pb.Static
if err := json.Unmarshal(res["Static"], &static); err != nil {
    return nil, status.Errorf(codes.Internal, "Static data err %s", err)
}
var dynamic pb.Dynamic
if err := json.Unmarshal(res["Dynamic"], &dynamic); err != nil {
    return nil, status.Errorf(codes.Internal, "Dynamic data err %s", err)
}

解组有效负载时我做错了,但我无法弄清楚到底是什么。

这是一个示例游乐场:go.dev/play/p/9e7a63hNMEA

【问题讨论】:

  • 请编辑问题并包含有问题的 JSON。 SQLC 生成的代码应该只返回数据库中的任何内容(您可以使用类似fmt.Printf("%s\n", testingData.Content) 的内容来确认这一点)。
  • 抱歉,我认为这会使问题变得混乱。完成后,按照建议将 JSON 包含在 print 语句中。

标签: go sqlc


【解决方案1】:

您的 JSON 包含 staticdynamic 键。您正在解析为map[string]json.RawMessage,然后尝试从地图中检索StaticDynamic(注意大写)。

修复映射键(即json.Unmarshal(res["static"], &static)),您的代码将变为probably work。更好的解决方案可能是在尝试解组之前检查密钥是否存在。

【讨论】:

  • 感谢您的帮助,至少我发现了为什么我无法在控制台上打印第一部分。大写...但我仍然有同样的问题。这是操场上的示例:go.dev/play/p/9e7a63hNMEA
猜你喜欢
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
相关资源
最近更新 更多