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

Phoenix迁移时Postgres插入数据遇inserted_at约束及子查询报错求助

解决Postgrex的非空约束错误与子查询列数不匹配问题

我来帮你梳理下问题所在,以及对应的解决办法:

首先看第一个错误:null value in column "inserted_at" violates not-null constraint,原因很直接——你的contract_groups表要求inserted_at字段不能为null,但你最初的INSERT语句只插入了contract_id和group_id,完全没给inserted_at赋值,PostgreSQL自然会触发非空约束报错。

然后你修改后的SQL出现了subquery must return only one column错误,是因为你把返回两列的子查询塞进了VALUES的单个位置里。VALUES里每个逗号分隔的项只能对应单列值,而你(SELECT c.id, fg.group_id ...)返回了两列,这就和语法要求冲突了,这种写法根本不适合批量插入多列数据的场景。

正确的写法应该是这样

直接在原来的INSERT ... SELECT语法里补上inserted_at的取值就行,不用绕去VALUES:

execute "INSERT INTO contract_groups (contract_id, group_id, inserted_at)
SELECT c.id, fg.group_id, NOW()
FROM contracts c, folder_groups fg 
WHERE c.folder_id = fg.folder_id"

如果你的表还有updated_at这类同样非空的字段,也一起加上:

execute "INSERT INTO contract_groups (contract_id, group_id, inserted_at, updated_at)
SELECT c.id, fg.group_id, NOW(), NOW()
FROM contracts c, folder_groups fg 
WHERE c.folder_id = fg.folder_id"

为什么这个写法能解决问题?

  • 保持了INSERT ... SELECT批量插入的优势,适合从关联表中一次性取数插入
  • 显式指定了要插入的列名,避免因为表字段顺序变化导致的错误
  • 在SELECT语句里直接用NOW()(或者CURRENT_TIMESTAMP,效果一致)给inserted_at(和updated_at)赋值,满足非空约束的要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:19:51