You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS中使用Postgres的COPY命令实现大数据批量写入

错误原因

你当前的写法不符合Postgres的COPY FROM STDIN协议要求:psql控制台能直接运行带行数据的COPY语句,是因为psql客户端自行处理了stdin输入逻辑,将COPY语句和后续行数据分开传输给数据库。而普通的SQL查询接口只能接收标准SQL语句,不支持直接在COPY语句后拼接行数据和结束符\.,因此会报语法错误。

可行实现方案

要在Node.js/TypeORM场景下使用COPY批量插入,推荐使用pg-copy-streams库配合Postgres原生的流复制协议实现,性能可以满足千万级数据的写入需求。

步骤1:安装依赖

# 核心依赖
npm install pg-copy-streams
# TypeScript 类型补充(非TS项目可忽略)
npm install @types/pg-copy-streams -D

步骤2:代码实现

import { from } from 'pg-copy-streams';
import { Readable } from 'stream';
import { pipeline } from 'stream/promises';

// 业务逻辑代码
const queryRunner = this.connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();

try {
  // 拿到TypeORM封装的原生Postgres客户端
  const pgClient = (queryRunner as any).databaseConnection;

  // 构造COPY语句,可根据需求调整格式、分隔符、空值标识等参数
  const copyQuery = `COPY ${table}(key) FROM STDIN WITH (FORMAT text, DELIMITER E'\t', NULL '\\N')`;
  const copyStream = pgClient.query(from(copyQuery));

  // 构造待插入数据的可读流,千万级数据建议边读边写避免内存溢出
  const dataRows = ['123', '321', '147'];
  const inputStream = Readable.from(
    dataRows.map(row => `${row}\t\n`).join('')
    // 多字段场景按COPY字段顺序拼接:`${field1}\t${field2}\t${field3}\n`
  );

  // 等待流传输完成
  await pipeline(inputStream, copyStream);

  await queryRunner.commitTransaction();
} catch (err) {
  await queryRunner.rollbackTransaction();
  throw err;
} finally {
  await queryRunner.release();
}

替代方案(百万级以内数据适用)

如果你的数据量级不超过百万,不想引入额外依赖,可以使用Postgres的unnest函数实现批量插入,性能远高于逐行INSERT,写法更简单:

const keys = ['123', '321', '147'];
await queryRunner.query(
  `INSERT INTO ${table}(key) SELECT * FROM unnest($1::text[])`,
  [keys]
);
注意事项
  • 多字段插入时需严格按照COPY语句中指定的字段顺序拼接值,注意转义字段中的分隔符、换行符、反斜杠等特殊字符
  • 千万级数据插入不要一次性加载所有数据到内存,需对接API的输入流边解析边写入COPY流,避免OOM
  • CSV格式数据可修改COPY语句的FORMAT为csv,按需配置分隔符、引号、是否忽略表头即可

内容的提问来源于stack exchange,提问作者Getsumi3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:36:04