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
);
Run Code Online (Sandbox Code Playgroud)
现在想在存储过程中填充这些类型,它将json作为输入参数.这适用于顶级字段,输出显示postgres复合类型的内部格式:
# select json_populate_record(null::customer, '{"customer_number":"12345678"}'::json)::customer;
json_populate_record
----------------------
(12345678,,,)
(1 row)
Run Code Online (Sandbox Code Playgroud)
但是,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.
Run Code Online (Sandbox Code Playgroud)
再次起作用的是,如果嵌套属性是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)
Run Code Online (Sandbox Code Playgroud)
有没有办法让postgres从嵌套的json结构转换为相应的复合类型?
plpython来救援:
create function to_customer (object json)
returns customer
AS $$
import json
return json.loads(object)
$$ language plpythonu;
Run Code Online (Sandbox Code Playgroud)
例子:
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)
Run Code Online (Sandbox Code Playgroud)
警告:当从 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"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1157 次 |
| 最近记录: |