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

Node.js读取JSON批量插入PostgreSQL出现语法错误问题排查

问题原因
  1. pg-format批量插入要求传入二维数组,你当前的intakes是对象数组,直接用%L格式化时会把每个对象整体序列化为字符串,而非将对象属性拆分为单独的字段值,导致SQL中出现一整个被单引号包裹的JSON字符串,直接触发语法错误。
  2. 调用client.query时重复传入了intakes参数:你已经通过pg-format把值拼接进SQL语句,不需要再传第二个参数,否则pg会将其识别为预编译占位符的对应值,引发额外语法问题。
  3. 存在冗余导入:第一行const pg = require('pg');和第二行const { Pool } = require('pg');功能重复,可以合并。
解决办法

首先将对象数组转换为二维数组,每个子数组对应一条记录的字段值,顺序要和INSERT语句中的字段顺序完全对应,之后修正SQL生成逻辑和查询调用即可,修正后的代码如下:

const { Pool } = require('pg');
const format = require('pg-format');
const fs = require('fs');

// 读取并解析JSON文件
const rawintakes = fs.readFileSync('./data/intakes.json', 'utf8');
const intakes = JSON.parse(rawintakes);

// 转换为pg-format要求的二维数组结构,字段顺序和INSERT声明的顺序严格对齐
const values = intakes.map(item => [
  item.Archived,
  item.ClientEmail,
  item.ClientId,
  item.ClientName,
  item.DateCreated,
  item.DateSubmitted,
  item.ExternalClientId,
  item.Id,
  item.Practitioner,
  item.PractitionerId,
  item.PractitionerName,
  item.QuestionnaireId,
  item.QuestionnaireName,
  item.Status
]);

// 生成合法的批量插入SQL
const query1 = format('INSERT INTO intake_summary (Archived, ClientEmail, ClientId, ClientName, DateCreated, DateSubmitted, ExternalClientId, Id, Practitioner, PractitionerId, PractitionerName, QuestionnaireId, QuestionnaireName, Status) VALUES %L returning id', values);

async function run() {
  let client;
  try {
    client = new Pool({
      connectionString: 'postgres://postres:reallystrongpassword@localhost:5432/cldba01'
    });
    await client.connect();
    // 已拼接好SQL,无需传入第二个参数
    const {rows} = await client.query(query1);
    console.log(rows);
  } catch (e) {
    console.error(e);
  } finally {
    client.end();
  }
}

run();

如果需要规避SQL注入风险,也可以改用pg的预编译批量插入语法,通过生成对应数量的$n占位符或者调用unnest函数实现,上述写法已经可以解决你当前遇到的报错问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:54:04