TypeORM迁移转换PostgreSQL timestamp时区类型时数据被置空如何解决
问题原因
TypeORM的changeColumn方法修改列类型时,默认没有配置旧值到新类型的转换逻辑,执行时会先创建临时新列、写入数据失败后删除旧列、重命名新列,最终导致原有数据全部被置为null。同时PostgreSQL在转换timestamp without time zone到timestamp with time zone类型时,需要显式指定时区映射规则,才能正确完成值转换。
解决方案
直接使用原生SQL执行类型变更,通过USING子句指定时区转换规则即可保留原有数据,修改后的迁移代码如下:
import { MigrationInterface, QueryRunner } from 'typeorm'; export class appointmentDateTimeWithTimeZone1625773516977 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise<void> { // 如果你原有无时区时间是按UTC存储的,就用AT TIME ZONE 'UTC' // 如果是其他时区存储的,替换为对应时区即可,比如东八区用'Asia/Shanghai' await queryRunner.query(` ALTER TABLE "case" ALTER COLUMN "appointment_date_time" TYPE timestamp with time zone USING "appointment_date_time" AT TIME ZONE 'UTC' `); } public async down(queryRunner: QueryRunner): Promise<void> { // 回滚时同样指定时区规则,把带时区时间转回无时区时间 await queryRunner.query(` ALTER TABLE "case" ALTER COLUMN "appointment_date_time" TYPE timestamp without time zone USING "appointment_date_time" AT TIME ZONE 'UTC' `); } }
注意事项
迁移执行完成后,需要同步修改实体的@Column定义,把type字段更新为timestamp with time zone,避免后续TypeORM schema同步逻辑异常。
内容的提问来源于stack exchange,提问作者Alex Chen
相关产品推荐
相关产品推荐

