Prisma迁移ConfigItem时设置id报错:未知参数id
问题
将遗留应用迁移至NextJS+PrismaJS项目,通过mjs文件执行标准MySQL查询获取原数据,再用Prisma将数据导入新数据库,需保留原数据库的ID。目前近30张表均迁移正常,但ConfigItem表调用prisma.configItem.create()设置id时,抛出「Unknown argument id」错误。移除id字段则可自动递增正常导入。
相关Prisma Schema
model ConfigGroup { id Int @id @default(autoincrement()) name String @db.VarChar(255) config_items ConfigItem[] config_values ConfigValue[] @@map("config_groups") } model ConfigItem { id Int @id @default(autoincrement()) config_group_id Int name String @db.VarChar(255) title String @db.VarChar(255) type ConfigItemType function_call_name String @db.VarChar(255) description String @db.MediumText value String @db.MediumText placeholder_text String @db.VarChar(255) storage_type ConfigItemStorageType @default(TEXT) required Boolean @default(false) config_group ConfigGroup @relation(fields: [config_group_id], references: [id]) config_values ConfigValue[] @@map("config_items") } model ConfigValue { id Int @id @default(autoincrement()) config_group_id Int? config_item_id Int? value String @db.VarChar(255) config_groups ConfigGroup? @relation(fields: [config_group_id], references: [id]) config_items ConfigItem? @relation(fields: [config_item_id], references: [id]) @@map("config_values") }
正常运行的ConfigGroup迁移代码
return nodePrisma.$transaction(async (nodePrisma) => { let [rows] = await this.getData("config_groups"); for (const row of rows) { await nodePrisma.configGroup.create({ data: { id: row.id, name: row.Name } }) } console.log("Config groups successfully migrated"); });
报错的ConfigItem迁移代码
return nodePrisma.$transaction(async (nodePrisma) => { for (const row of rows) { // 检查配置组ID是否存在 const configGroup = await nodePrisma.configGroup.findUnique({ where: { id: parseInt(row.ConfigGroupID) } }); if (configGroup === null) { continue; } let type; switch (row.Type) { case "Text": type = ConfigItemType.TEXT; break; case "MultiText": type = ConfigItemType.MULTI_TEXT; break; case "Number": type = ConfigItemType.NUMBER; break; case "Email": type = ConfigItemType.EMAIL; break; case "Password": type = ConfigItemType.DROPDOWN; break; case "Function": type = ConfigItemType.FUNCTION; break; case "Dropdown": type = ConfigItemType.DROPDOWN; break; default: console.error("Unknown config item type: " + row.Type); return; } let storageType; switch (row.StorageType) { case "TEXT": storageType = ConfigItemStorageType.TEXT; break; case "JSON": storageType = ConfigItemStorageType.JSON; break; default: console.error("Unknown config item storage type: " + row.StorageType); return; } // 无法理解为何这里不能设置id,持续抛出id是未知参数的错误 await nodePrisma.configItem.create({ data: { id: row.id, //config_group_id: configGroup.id, config_group: { connect: { id: configGroup.id } }, name: row.Name, title: row.Title, type: type, function_call_name: row.FunctionCallName, description: row.Description, value: row.Value, placeholder_text: row.PlaceholderText ?? "", storage_type: storageType, required: row.Required === "1" } }) }
报错信息
PrismaClientValidationError: Invalid `prisma.configItem.create()` invocation: { data: { id: 1, ~~ config_group: { connect: { id: 1 } }, name: "DefaultQuoteAssignees", title: "Default Quote Assignee", type: "FUNCTION", function_call_name: "GetAllActiveUsers", description: "What user should be automatically selected", value: "[\"9\",\"10\"]", placeholder_text: "", storage_type: "JSON", required: false, ? config_values?: ConfigValueCreateNestedManyWithoutConfig_itemsInput } } Unknown argument `id`. Available options are marked with ?.
核心疑问:ConfigItem模型的id字段定义与ConfigGroup一致,代码逻辑也类似,为何只有ConfigItem无法手动设置id?
解决方案
原因分析
Prisma中,标记为@id @default(autoincrement())的字段默认允许手动传入id值,但出现这个错误通常是以下两种情况:
- 修改ConfigItem的schema后,未重新生成Prisma客户端,导致客户端的类型定义未同步,仍认为id字段不可手动传入;
- 数据库中该字段的自增约束配置特殊,或当前数据库用户权限不足,无法手动插入自增ID值。
解决步骤
重新生成Prisma客户端
这是最常见的解决方法,在项目根目录执行命令,确保客户端代码与最新schema同步:npx prisma generate确认数据库允许手动插入自增ID
对于MySQL,自增字段默认支持手动插入,但可临时执行SQL调整模式,确保能插入指定ID:SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';迁移完成后可恢复原有配置。
改用upsert方法(可选)
如果重新生成客户端后问题仍存在,可尝试用upsert替代create,规避客户端校验问题:await nodePrisma.configItem.upsert({ where: { id: row.id }, update: {}, create: { id: row.id, config_group: { connect: { id: configGroup.id } }, name: row.Name, title: row.Title, type: type, function_call_name: row.FunctionCallName, description: row.Description, value: row.Value, placeholder_text: row.PlaceholderText ?? "", storage_type: storageType, required: row.Required === "1" } })检查枚举定义完整性
确保ConfigItemType和ConfigItemStorageType已在schema中正确定义,且已生成到客户端。枚举定义缺失或不完整可能引发客户端解析异常,间接导致字段识别错误。
内容的提问来源于stack exchange,提问作者Boardy
相关产品推荐
相关产品推荐

