【问题标题】:Postgres, jsonb & jsonb_setPostgres、jsonb 和 jsonb_set
【发布时间】:2017-07-21 15:07:27
【问题描述】:

根据 HTTP_USER_AGENT,我必须向客户端返回一个非常专业的 json 结构格式版本。

json 对象像往常一样使用标准 postgres 函数生成。 让我们假设生成的 json 看起来像这样:

{
    "return_code" : 0,
    "payload" : {
        "name" : "smith",
        "age": 17,
        "address" :{
            "street" : "<whatever>",
            "city" : "<anycity>"
        }
    }
}

现在在某些情况下,我必须以以下格式返回这个 json:

{
    "return_code" : 0,
    "payload" : "{"name" : "smith", "age": 17, "address" :"{"street" : "<whatever>", "city" : "<anycity>"}"}"
}

如您所见,嵌套的有效负载对象应作为字符串返回 - 此处忽略掩码以提高可读性。

此外,地址属性也应该作为字符串返回,而不是作为 json 对象。

我应该这样做的 postgres 代码很简单:

response := jsonb_set(response, '{payload}', to_jsonb((response->'payload')::text));

但是上面代码的结果是这样的:

{
    "return_code" : 0,
    "payload" : "{"name" : "smith", "age": 17, "address" :{"street" : "<whatever>", "city" : "<anycity>"}}"
}

考虑地址对象缺少引号(只有两个)。 我该如何解决这个问题?

谢谢!

【问题讨论】:

    标签: json postgresql


    【解决方案1】:

    在我看来,您需要在 address 属性上进行进一步的转义/引用,因为您有:

    • 你的替换:{ "payload" : { ... } } -> { "payload" : "{ ... }" }
    • 额外替换:{ "address": { ... } } -> { "address": "{ ... }" }

    您需要现有行之前执行此操作,所以我认为您想要的是这个(需要一个额外的jsonb 变量,payload):

    payload := jsonb_set(response->'payload', '{address}', to_jsonb((response->'payload'->address)::text));
    response := jsonb_set(response, '{payload}', to_jsonb(payload::text));
    

    【讨论】:

    • 确实,这应该是可能的。但这只是一个示例。返回的可能的 json 结构在有效负载对象中可能完全不同。我只想在处理结束时创建任何结构后以通用方式进行转换。
    • @CyrilDamm 那么你需要一些关于结构如何变化的定义 - 是否总是最多两个级别需要双引号?或者您有时可能需要{ "foo": "{"bar": "{ "baz": "{ ... }" }" }" },或更深层次的递归?内部数组是否也需要双引号? (另外,我害怕认为另一端的解析器需要像这样递归引用;我可以理解引用单个 payload 部分,但不确定为什么需要进一步操作。)
    猜你喜欢
    • 2016-12-17
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多