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

使用node-postgres导入JSON数据至PostgreSQL表遇非空约束错误求助

问题分析与解决

错误原因

你遇到的问题源于两个核心问题:

  1. 非标准JSON格式:你提供的JSON中属性名未用双引号包裹,不符合JSON规范。使用JSON.stringify(books)处理时,会导致键名无法被PostgreSQL正确识别,最终提取的值为NULL。
  2. 大小写不匹配:PostgreSQL默认会将未加引号的标识符(如列名)转为小写。如果你的books表列名是小写的title/author/genre,而JSON中的键是大写开头的Title/Author/Genre,json_populate_recordset会因键名不匹配返回NULL,触发非空约束。

修复步骤

1. 修正JSON格式

首先确保你的JSON是标准格式,属性名必须用双引号包裹:

[
  {
    "Title": "abc",
    "Author": "abc",
    "Genre": "abc"
  }
]

2. 选择合适的SQL写法

根据你的表列名情况,选择以下两种方式之一:

方式一:适配小写列名(推荐)

如果你的表列名是小写的title/author/genre,用json_array_elements手动映射键与列:

export async function insert () {
    return await pool.query (
        `INSERT INTO books (title, author, genre)
         SELECT 
           (data->>'Title')::text AS title,
           (data->>'Author')::text AS author,
           (data->>'Genre')::text AS genre
         FROM json_array_elements($1::JSON) AS data;`,
        [JSON.stringify(books)]
    );
}

方式二:保留大小写匹配(不推荐)

如果你的表列名确实是大写的Title/Author/Genre,需要在SQL中给列名加双引号强制区分大小写:

export async function insert () {
    return await pool.query (
        `INSERT INTO books ("Title", "Author", "Genre")
         SELECT "Title", "Author", "Genre"
         FROM json_populate_recordset(NULL::books, $1::JSON);`,
        [JSON.stringify(books)]
    );
}

3. 验证JSON导入过程

确保你导入JSON文件时用了正确的解析方式,比如:

// 读取本地JSON文件示例
import fs from 'fs/promises';

const books = JSON.parse(await fs.readFile('./your-books.json', 'utf8'));

避免使用非标准的JSON解析工具,确保books对象的键名是Title/Author/Genre。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:25:20