Prisma中修改Asset表id类型且保留关联关系的方法
单次迁移完成Asset id类型从Int转String并保留关联的方案
你可以通过自定义Prisma迁移在单次操作中完成,核心思路是先建立新的String类型关联,再替换旧的主键和外键,全程保留数据关联关系。具体步骤如下:
1. 准备临时Prisma Schema(仅用于生成迁移文件)
先临时修改schema,添加过渡字段,避免自动生成的迁移破坏现有数据关联:
model Asset { id Int @id @default(autoincrement()) newId String? @unique // 临时过渡用的String类型字段 name String? shapefile Shapefile? } model Shapefile { id Int @id @default(autoincrement()) // 补充Shapefile的基础主键(若之前未定义) assetId Int? newAssetId String? // 临时过渡用的关联字段 asset Asset @relation(fields: [assetId], references: [id]) }
2. 生成空迁移文件
运行命令生成可编辑的空迁移文件:
prisma migrate dev --create-only
3. 编写自定义迁移SQL
打开生成的迁移文件(路径:prisma/migrations/[时间戳]_xxx/migration.sql),替换为对应数据库的SQL逻辑(以下以PostgreSQL为例,MySQL语法需自行调整):
-- 1. 给Asset填充newId:将原Int类型id转为String,或生成UUID UPDATE "Asset" SET "newId" = CAST("id" AS VARCHAR(255)); -- 若要改用UUID,替换为:UPDATE "Asset" SET "newId" = gen_random_uuid(); -- 2. 给newId设置非空约束 ALTER TABLE "Asset" ALTER COLUMN "newId" SET NOT NULL; -- 3. 给Shapefile填充newAssetId:关联原assetId与Asset的newId UPDATE "Shapefile" s SET "newAssetId" = a."newId" FROM "Asset" a WHERE s."assetId" = a."id"; -- 4. 删除Shapefile的旧外键约束(约束名可通过数据库查询获取,通常为Shapefile_assetId_fkey) ALTER TABLE "Shapefile" DROP CONSTRAINT "Shapefile_assetId_fkey"; -- 5. 删除Shapefile的旧assetId列 ALTER TABLE "Shapefile" DROP COLUMN "assetId"; -- 6. 重命名newAssetId为assetId ALTER TABLE "Shapefile" RENAME COLUMN "newAssetId" TO "assetId"; -- 7. 给Shapefile的新assetId添加外键关联到Asset的newId ALTER TABLE "Shapefile" ADD CONSTRAINT "Shapefile_assetId_fkey" FOREIGN KEY ("assetId") REFERENCES "Asset"("newId") ON DELETE RESTRICT ON UPDATE CASCADE; -- 8. 删除Asset的旧主键约束(通常为Asset_pkey) ALTER TABLE "Asset" DROP CONSTRAINT "Asset_pkey"; -- 9. 删除Asset的旧id列 ALTER TABLE "Asset" DROP COLUMN "id"; -- 10. 重命名newId为id ALTER TABLE "Asset" RENAME COLUMN "newId" TO "id"; -- 11. 给新id设置主键约束 ALTER TABLE "Asset" ADD CONSTRAINT "Asset_pkey" PRIMARY KEY ("id");
4. 更新最终Prisma Schema
替换为最终模型定义(移除临时字段,设置String类型的id):
model Asset { id String @id @default(uuid()) // 若保留原Int转String的id,可去掉@default(uuid()),但建议用UUID保证唯一性 name String? shapefile Shapefile? } model Shapefile { id Int @id @default(autoincrement()) assetId String asset Asset @relation(fields: [assetId], references: [id]) }
5. 执行迁移
运行命令完成整个迁移流程:
prisma migrate dev
注意事项
- 操作前务必备份数据库,避免数据丢失
- 不同数据库的SQL语法存在差异(比如MySQL的关联更新写法、约束命名规则),需根据你的数据库类型调整
- 若选择UUID作为新id,需确保数据库支持对应生成函数(PostgreSQL用
gen_random_uuid(),MySQL用UUID())
内容的提问来源于stack exchange,提问作者LeavingValhalla
相关产品推荐
相关产品推荐

