使用node-postgres导入JSON数据至PostgreSQL表遇非空约束错误求助
问题分析与解决
错误原因
你遇到的问题源于两个核心问题:
- 非标准JSON格式:你提供的JSON中属性名未用双引号包裹,不符合JSON规范。使用
JSON.stringify(books)处理时,会导致键名无法被PostgreSQL正确识别,最终提取的值为NULL。 - 大小写不匹配: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
相关产品推荐
相关产品推荐

