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

TypeORM生成MySQL迁移:如何将createdAt/updatedAt设为timestamp并解决错误

问题:TypeORM生成MySQL迁移时timestamp字段默认值错误

我在项目中使用MySQL + TypeORM,定义了如下实体:

export const CompanyRadarTypeEntity = new EntitySchema<ICompanyRadarTypeEntity>({    
    name: 'companyRadarType',    
    tableName: 'companyRadarType',    
    columns: {        
        idCompanyRadarType: {            
            type: Number,            
            primary: true,            
            generated: true,        
        },        
        type: {            
            type: String,        
        },        
        idCompany: {            
            type: Number,        
        },        
        createdAt: {            
            type: 'timestamp',            
            default: () => 'CURRENT_TIMESTAMP',            
            nullable: false,            
            createDate: true,        
        },        
        updatedAt: {            
            type: 'timestamp',            
            default: () => 'CURRENT_TIMESTAMP',            
            nullable: false,            
            updateDate: true,        
        },    
    },    
    relations: {        
        company: {            
            type: 'many-to-one',            
            target: 'company',            
            joinColumn: {                
                name: 'idCompany',                
                referencedColumnName: 'idCompany',            
            },        
        },        
        companyRadars: {            
            type: 'one-to-many',            
            target: 'companyRadar',            
            inverseSide: 'companyRadarType',        
        },    
    },
});

使用TypeORM生成迁移后,得到如下SQL:

await queryRunner.query(`            
    CREATE TABLE \`companyRadarType\` (                
        \`idCompanyRadarType\` int NOT NULL AUTO_INCREMENT,                
        \`type\` varchar(255) NOT NULL,                
        \`idCompany\` int NOT NULL,                
        \`createdAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,                
        \`updatedAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(6),                
        PRIMARY KEY (\`idCompanyRadarType\`)            
    ) ENGINE = InnoDB        
`);

执行迁移时触发错误:

Error during migration run: QueryFailedError: ER_INVALID_DEFAULT: Invalid default value for 'createdAt'

若移除实体中的createDate: true和updateDate: true,字段类型虽为timestamp,但updatedAt会丢失ON UPDATE CURRENT_TIMESTAMP的自动更新逻辑。


解决方案

方法1:调整实体字段的默认值精度

MySQL严格模式下,timestamp(6)字段的默认值必须匹配精度。修改实体中createdAt和updatedAt的default配置,明确指定6位精度:

createdAt: {
    type: 'timestamp',
    default: () => 'CURRENT_TIMESTAMP(6)', // 和字段精度保持一致
    nullable: false,
    createDate: true,
},
updatedAt: {
    type: 'timestamp',
    default: () => 'CURRENT_TIMESTAMP(6)',
    nullable: false,
    updateDate: true,
},

重新生成迁移后,SQL中的默认值会自动匹配字段精度,解决默认值无效的问题,同时保留createdAt和updatedAt的自动维护逻辑。

方法2:手动修正迁移文件的SQL

如果不想修改实体配置,直接编辑生成的迁移SQL,将createdAt的默认值改为CURRENT_TIMESTAMP(6):

`createdAt` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),

修改后执行迁移即可正常运行,同时保留updatedAt的ON UPDATE逻辑。

方法3:调整MySQL的sql_mode配置(不推荐)

错误可能源于MySQL的sql_mode包含NO_ZERO_DATE或NO_ZERO_IN_DATE规则。可以临时修改会话级别的sql_mode:

SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

也可以修改MySQL配置文件(my.cnf/my.ini)中的sql_mode,移除NO_ZERO_DATE和NO_ZERO_IN_DATE后重启服务。但这种方法会降低数据校验的严格性,仅作为临时应急方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:10:21