解决Prisma迁移报错:used key part isn't a string(错误码1089)
解决Prisma迁移部署MySQL时的1089错误
问题背景
本地用Prisma开发MySQL数据库运行正常,但部署到外部环境时迁移失败,执行的迁移脚本如下:
-- DropForeignKey ALTER TABLE `Invoices` DROP FOREIGN KEY `Invoices_promoCodesId_fkey`; -- AlterTable ALTER TABLE `Invoices` DROP COLUMN `promoCodesId`, ADD COLUMN `PromoCodesId` INTEGER NULL; -- AddForeignKey ALTER TABLE `Invoices` ADD CONSTRAINT `Invoices_PromoCodesId_fkey` FOREIGN KEY (`PromoCodesId`) REFERENCES `PromoCodes`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
报错信息:
Database error code: 1089 Database error: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
解决步骤
1. 核对表结构与存储引擎
- 确认
PromoCodes表的id字段类型为INTEGER,且是主键(PRIMARY KEY),和迁移脚本中Invoices.PromoCodesId的类型完全匹配。 - 检查两张表的存储引擎是否一致(建议都用
InnoDB,MyISAM不支持外键且索引规则不同),执行命令查看:SHOW CREATE TABLE `PromoCodes`; SHOW CREATE TABLE `Invoices`;
2. 统一列名大小写
MySQL在Linux环境下默认区分表名/列名大小写,Windows环境则不区分。本地(可能是Windows)能正常运行,但部署环境(Linux)会因大小写不匹配导致索引创建失败。修改迁移脚本,统一列名大小写:
-- DropForeignKey ALTER TABLE `Invoices` DROP FOREIGN KEY `Invoices_promoCodesId_fkey`; -- AlterTable ALTER TABLE `Invoices` DROP COLUMN `promoCodesId`, ADD COLUMN `promoCodesId` INTEGER NULL; -- 改为和原列名一致的小写,或与关联表主键列名大小写匹配 -- AddForeignKey ALTER TABLE `Invoices` ADD CONSTRAINT `Invoices_promoCodesId_fkey` FOREIGN KEY (`promoCodesId`) REFERENCES `PromoCodes`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
3. 检查索引前缀设置
如果PromoCodes.id是字符串类型(与脚本标注的INTEGER不符),需确认是否设置了过长的索引前缀。确保外键关联列的长度与主键长度一致,且无不合理的前缀配置。
4. 分步手动执行迁移
若自动迁移报错,可拆分步骤手动执行:
- 删除原外键:
ALTER TABLE `Invoices` DROP FOREIGN KEY `Invoices_promoCodesId_fkey`; - 删除原列:
ALTER TABLE `Invoices` DROP COLUMN `promoCodesId`; - 新增匹配列:
ALTER TABLE `Invoices` ADD COLUMN `promoCodesId` INTEGER NULL; - 创建外键:
ALTER TABLE `Invoices` ADD CONSTRAINT `Invoices_promoCodesId_fkey` FOREIGN KEY (`promoCodesId`) REFERENCES `PromoCodes`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
5. 校验Prisma Schema一致性
检查schema.prisma中两张表的关联定义,确保列名、类型完全匹配,例如:
model Invoices { id Int @id @default(autoincrement()) promoCodesId Int? PromoCodes PromoCodes? @relation(fields: [promoCodesId], references: [id]) // 其他字段 } model PromoCodes { id Int @id @default(autoincrement()) Invoices Invoices[] // 其他字段 }
内容的提问来源于stack exchange,提问作者Alex Buznik
相关产品推荐
相关产品推荐

