You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TypeORM插入Service数据时指定字段值未被正确传入,触发PostgreSQL非空约束错误

解决TypeORM插入时外键字段被设为DEFAULT导致的非空约束错误

看起来你遇到的问题是:明明已经给idUseridServiceCategory赋值了,但TypeORM生成的SQL里却把这两个字段设为DEFAULT,最终触发PostgreSQL的非空约束错误。这大概率是实体类(Service)的字段映射配置有问题,下面给你一步步排查和解决的方案:

核心原因分析

TypeORM只会处理实体类中通过装饰器(比如@Column@JoinColumn)显式声明的字段。如果你的Service实体里没有正确映射idUseridServiceCategory这两个外键字段,即使你通过Object.assign给对象添加了这些属性,TypeORM也不会把它们当作数据库列来处理,最终就会在SQL里用DEFAULT代替。

解决方案

根据你的实体定义方式,分两种情况处理:

情况1:你想直接操作外键ID字段

如果你的数据库表确实有idUseridServiceCategory这两个列,并且你希望直接给这些ID赋值,那么需要在Service实体中显式声明这两个字段,并配置正确的@Column装饰器:

import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from "typeorm";

@Entity()
export class Service {
  @PrimaryGeneratedColumn("uuid")
  id: string;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

  @Column({ nullable: false })
  title: string;

  @Column()
  description: string;

  @Column({ nullable: false })
  createdBy: string;

  @Column({ default: false })
  closed: boolean;

  // 关键:显式声明外键字段,确保和数据库列名一致,且nullable设为false
  @Column({ name: "idUser", nullable: false })
  idUser: string;

  @Column({ name: "idServiceCategory", nullable: false })
  idServiceCategory: string;
}

这样配置后,TypeORM就能正确识别这两个字段,插入时会把你赋值的ID写入SQL。

情况2:你使用TypeORM的关系关联(比如@ManyToOne)

如果你的Service实体是通过关系字段关联UserServiceCategory的(比如定义了userserviceCategory属性),那么直接给idUser赋值是无效的——TypeORM会忽略未被装饰器声明的属性。此时应该通过关系字段来关联,而不是直接操作外键ID:

首先,确保实体的关系配置正确:

import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from "typeorm";
import { User } from "./User";
import { ServiceCategory } from "./ServiceCategory";

@Entity()
export class Service {
  // ...其他字段省略

  // 关联User实体
  @ManyToOne(() => User)
  @JoinColumn({ name: "idUser" }) // 指定数据库外键列名
  user: User;

  // 关联ServiceCategory实体
  @ManyToOne(() => ServiceCategory)
  @JoinColumn({ name: "idServiceCategory" })
  serviceCategory: ServiceCategory;
}

然后修改你的路由代码,通过关系字段来赋值(不需要直接设置idUseridServiceCategory):

const newService: Service = Object.assign(new Service(), {
  ...service,
  user: { id: idUser } as User, // 用ID关联User,TypeORM会自动处理外键
  serviceCategory: { id: service.idServiceCategory } as ServiceCategory,
  createdBy: idUser
});

这样TypeORM生成SQL时,会自动把关系对象的ID写入对应的外键列,不会再用DEFAULT填充。

额外检查点

  • 确认你的Service实体中,idUseridServiceCategorynullable属性都设为false,和数据库的非空约束保持一致。
  • 如果开启了TypeORM的synchronize: true模式,确保实体配置的修改已经同步到数据库表结构中。

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

火山引擎 最新活动