NestJS+SQL Server将主键改为UUID是否影响现有记录?
NestJS+SQL Server修改主键类型的安全方案
直接修改实体主键为UUID并开启synchronize: true的话,现有记录会全部丢失——因为SQL Server不支持直接修改主键的数据类型,TypeORM的同步机制会直接删除旧表,再根据新实体定义重建空表,原数据自然就没了,完全不符合你的需求。
针对非生产库的场景,给你两个安全的操作方案:
方案一:逐步迁移主键(保留原数据)
新增临时UUID列并填充数据
先通过SQL脚本给表加一个UUID类型的列,给现有每条记录生成UUID:-- 添加临时UUID列 ALTER TABLE ApiUsage ADD temp_uuid UNIQUEIDENTIFIER NULL; -- 给现有记录生成UUID值 UPDATE ApiUsage SET temp_uuid = NEWID();修改实体并同步结构
修改你的ApiUsage实体,注释掉原来的number类型主键id,新增string类型的uuid作为主键,同时保留原id字段(设为非主键、可空):import { Entity, PrimaryColumn, Column } from 'typeorm'; @Entity() export class ApiUsage { // 注释原主键 // @PrimaryGeneratedColumn() // id: number; @PrimaryColumn('uuid') uuid: string; // 保留原id作为临时字段 @Column({ nullable: true }) id: number; // 其他原有字段... }开启
synchronize: true让TypeORM同步结构,此时会创建新的主键列uuid,不会删除原数据。清理临时字段
确认新主键正常工作后,删除原id字段:- 先执行SQL脚本删除列:
ALTER TABLE ApiUsage DROP COLUMN id; - 再修改实体,删掉临时的
id字段定义,同步结构即可。
- 先执行SQL脚本删除列:
方案二:备份后重建(更简单,适合无外键场景)
备份现有数据
在SQL Server中导出ApiUsage表的所有数据为INSERT脚本(可以用SSMS的导出功能)。修改实体并重建表
修改实体的主键为UUID类型:@Entity() export class ApiUsage { @PrimaryColumn('uuid') uuid: string; // 其他原有字段... }开启
synchronize: true,TypeORM会删除旧表并创建新的空表。导入备份数据
修改之前导出的INSERT脚本,给每条记录的uuid字段添加NEWID()值(或提前生成好的UUID),然后执行脚本导入数据。
不管用哪种方案,都要确保操作前确认数据备份完成,非生产库虽然风险低,但也要谨慎操作。
内容的提问来源于stack exchange,提问作者Harish N
相关产品推荐
相关产品推荐

