TypeORM与PostgreSQL中如何实现等效于Mongoose的日期默认字段?
错误原因
你直接沿用Mongoose的写法之所以报错,是因为Date.now()返回的是毫秒级Unix时间戳(数值类型),而PostgreSQL的日期时间类型(timestamp/timestamptz/date)不支持直接接收数值类型的时间戳作为输入,因此抛出date/time field value out of range的错误。
等效实现方案
在TypeORM + PostgreSQL的技术栈下,有三种常用的实现方式,效果和你之前在Mongoose中的写法完全一致:
方案1:使用内置@CreateDateColumn装饰器(最推荐)
TypeORM内置了专门用于记录创建时间的装饰器,无需手动配置默认值,插入数据时会自动填充当前时间,默认映射PostgreSQL的timestamp with time zone类型:
import { Entity, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @CreateDateColumn() createdAt: Date; }
方案2:应用层生成默认值
如果你需要用@Column自定义字段配置,默认值需要返回Date实例而不是时间戳数值,且必须包装为箭头函数避免提前计算:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column({ type: 'timestamptz', default: () => new Date() }) createdAt: Date; }
方案3:数据库层生成默认值
也可以直接调用PostgreSQL内置的时间函数,由数据库生成默认值:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column({ type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' }) createdAt: Date; }
注意事项
- 禁止直接写
default: Date.now()或者default: new Date(),这两种写法会在类初始化时直接计算时间值,导致所有数据的默认创建时间都是服务启动时间,而非数据插入时间。 - 如果不需要时区信息,可以把字段
type改为timestamp;timestamptz会自动存储时区信息,更适配跨时区业务场景。
内容的提问来源于stack exchange,提问作者Angel Martinez
相关产品推荐
相关产品推荐

