可以控制JSONB序列化吗?

时间:2018-10-10 19:26:30

标签: postgresql postgresql-9.6

我想导出Postgres(v9.6)表中的jsonb列。

我尝试了COPY命令:

\COPY (SELECT my_json_column FROM my_table) to 'data.json';

我确实得到了一个JSON文件,但是我想做两个修改:

  1. 我要节省空间:定界符:,后没有空格。
  2. 我想要一个统一且可预测的键排序。

换句话说,我想要带有参数的Python json.dump的行为

  1. separators=(',',':')
  2. sort_keys=True

(这是摄取文件的格式,我想以相同的格式导出文件以检查往返是否是同一身份。)

2 个答案:

答案 0 :(得分:2)

没有用于格式化jsonb输出的内置选项。您可以使用PL/Python.

create extension if not exists plpython3u;

就目前(Postgres 10)而言,您必须使用Abstract Syntax Trees将Postgres jsonb转换为Python对象(在将来的版本中可能会自动转换)。

create or replace function format_jsonb(obj jsonb)
returns text language plpython3u as $$
    import json
    import ast
    js = ast.literal_eval(obj);
    return json.dumps(js, separators=(',', ':'), sort_keys=True)
$$;

使用:

select format_jsonb('{"abcd": 1, "jklm": 2, "jkl": 3, "abc": 4}');

            format_jsonb             
-------------------------------------
 {"abc":4,"abcd":1,"jkl":3,"jklm":2}
(1 row)

所以您的命令可能如下所示:

\COPY (SELECT format_jsonb(my_json_column) FROM my_table) to 'data.json';

答案 1 :(得分:0)

如果要保留原始格式,请不要使用jsonb。使用json来存储您输入的值。即使您设想了输出消息,重复的键也会丢失。

如果您需要jsonb设施,请将该列立即投射到jsonb。您仍然可以提高效率,因为您可以添加类似

的索引
CREATE INDEX ON mytab USING gin ((jsoncol::jsonb));