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

解决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. 分步手动执行迁移

若自动迁移报错,可拆分步骤手动执行:

  1. 删除原外键:
    ALTER TABLE `Invoices` DROP FOREIGN KEY `Invoices_promoCodesId_fkey`;
    
  2. 删除原列:
    ALTER TABLE `Invoices` DROP COLUMN `promoCodesId`;
    
  3. 新增匹配列:
    ALTER TABLE `Invoices` ADD COLUMN `promoCodesId` INTEGER NULL;
    
  4. 创建外键:
    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:05:14