Jör*_*ann 5 postgresql json composite-types
我在postgres中定义了以下嵌套类型:
CREATE TYPE address AS (
  name    text,
  street  text,
  zip     text,
  city    text,
  country text
);
CREATE TYPE customer AS (
  customer_number           text,
  created                   timestamp WITH TIME ZONE,
  default_billing_address   address,
  default_shipping_address  address
);
现在想在存储过程中填充这些类型,它将json作为输入参数.这适用于顶级字段,输出显示postgres复合类型的内部格式:
# select json_populate_record(null::customer, '{"customer_number":"12345678"}'::json)::customer;
 json_populate_record 
----------------------
 (12345678,,,)
(1 row)
但是,postgres不处理嵌套的json结构:
# select json_populate_record(null::customer, '{"customer_number":"12345678","default_shipping_address":{"name":"","street":"","zip":"12345","city":"Berlin","country":"DE"}}'::json)::customer;
ERROR:  malformed record literal: "{"name":"","street":"","zip":"12345","city":"Berlin","country":"DE"}"
DETAIL:  Missing left parenthesis.
再次起作用的是,如果嵌套属性是postgres的内部格式,如下所示:
# select json_populate_record(null::customer, '{"customer_number":"12345678","default_shipping_address":"(\"\",\"\",12345,Berlin,DE)"}'::json)::customer;
            json_populate_record            
--------------------------------------------
 (12345678,,,"("""","""",12345,Berlin,DE)")
(1 row)
有没有办法让postgres从嵌套的json结构转换为相应的复合类型?
plpython来救援:
create function to_customer (object json)
returns customer
AS $$
import json
return json.loads(object)
$$ language plpythonu;
例子:
select to_customer('{
        "customer_number":"12345678",
        "default_shipping_address":
        {
                "name":"",
                "street":"",
                "zip":"12345",
                "city":"Berlin",
                "country":"DE"
        },
        "default_billing_address":null,
        "created": null
}'::json);
                to_customer                 
--------------------------------------------
 (12345678,,,"("""","""",12345,Berlin,DE)")
(1 row)
警告:当从 python 构建返回的对象时,postgresql 要求所有null值都呈现为None(即不允许跳过不存在的空值),因此我们必须在传入的 json 中指定所有空值。例如,不允许:
select to_customer('{
        "customer_number":"12345678",
        "default_shipping_address":
        {
                "name":"",
                "street":"",
                "zip":"12345",
                "city":"Berlin",
                "country":"DE"
        } 
}'::json);                             
ERROR:  key "created" not found in mapping
HINT:  To return null in a column, add the value None to the mapping with the key named after the column.
CONTEXT:  while creating return value
PL/Python function "to_customer"
| 归档时间: | 
 | 
| 查看次数: | 1157 次 | 
| 最近记录: |