PostgreSQL 19: COPY TO 命令支持 JSON 格式

John Doe 三月 24, 2026

现在,JSON 已经成为了各数据处理平台通用的数据格式,COPY TO 命令支持 JSON 格式,让 PostgreSQL 可以和其他数据技术栈无缝集成。

image

特性提交日志

COPY TO 命令支持 JSON 格式。

本次更新为 COPY TO 命令新增了 JSON 格式选项,允许用户将查询结果或表数据直接导出为 JSON 对象流(每行一个对象,遵循 NDJSON 格式规范)。

当前 JSON 格式仅支持 COPY TO(数据导出)操作,暂未开放 COPY FROM(数据导入)的使用权限。

JSON 格式与部分标准文本 / CSV 格式化选项不兼容,包括 HEADER(表头)、DEFAULT(默认值)、NULL(空值)、DELIMITER(分隔符)、FORCE QUOTE(强制引号)、FORCE NOT NULL(强制非空)以及 FORCE NULL(强制空值)。

该特性已支持列列表指定功能:当显式指定列列表时,每个 JSON 对象中仅会输出指定名称的列。

讨论:https://postgr.es/m/CALvfUkBxTYy5uWPFVwpk_7ii2zgT07t3d-yR_cy4sfrrLU%3Dkcg%40mail.gmail.com

特性示例

Flink、Spark、ClickHouse 等大数据处理引擎均原生支持 NDJSON(换行分隔 JSON)格式的数据源,MongoDB、Elasticsearch 等文档数据库与搜索引擎,也原生支持 NDJSON 格式的批量导入。此前需要通过 SQL 函数或 ETL 工具转换格式,现在一条 COPY 命令即可直接生成符合要求的文件,无需任何中间处理。

通过本次提交,让 PostgreSQL 支持导出通用的 NDJSON 格式文件,从而可以被大数据工具直接消费。

创建测试表,并构造数据:

-- 创建用户测试表
CREATE TABLE IF NOT EXISTS users (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    mobile VARCHAR(11),
    email VARCHAR(100),
    status VARCHAR(20) DEFAULT 'active',
    create_time TIMESTAMPTZ DEFAULT NOW()
);

-- 插入测试数据
INSERT INTO users (id, name, mobile, email, status, create_time)
VALUES
(1, '张三', '13800138000', 'zhangsan@example.com', 'active', '2026-01-15 10:20:00+08'),
(2, '李四', '13900139000', 'lisi@example.com', 'active', '2026-02-20 14:30:00+08'),
(3, '王五', '13700137000', 'wangwu@example.com', 'inactive', '2025-12-05 09:10:00+08'),
(4, '赵六', '13600136000', 'zhaoliu@example.com', 'active', '2026-03-01 16:40:00+08');

-- 验证数据
SELECT * FROM users;

执行导出命令,全表导出为 NDJSON 文件(需超级用户或 pg_write_server_files 角色):

COPY users TO '/data/export/users.ndjson' WITH (FORMAT JSON);

带过滤条件的查询结果导出,仅同步活跃用户数据:

COPY (
  SELECT id, name, email 
  FROM users 
  WHERE status = 'active' AND create_time >= '2026-01-01'
) TO '/data/export/active_users_2026.ndjson' WITH (FORMAT JSON);

导出结果示例:

{"id":1,"name":"张三","email":"zhangsan@example.com"}
{"id":2,"name":"李四","email":"lisi@example.com"}
{"id":4,"name":"赵六","email":"zhaoliu@example.com"}

非常不错的体验,感谢所有参与的社区人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/7dadd38cda95bf5bc0c4715d9ab71766d1693379