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

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值,但出现这个错误通常是以下两种情况:

  1. 修改ConfigItem的schema后,未重新生成Prisma客户端,导致客户端的类型定义未同步,仍认为id字段不可手动传入;
  2. 数据库中该字段的自增约束配置特殊,或当前数据库用户权限不足,无法手动插入自增ID值。

解决步骤

  1. 重新生成Prisma客户端
    这是最常见的解决方法,在项目根目录执行命令,确保客户端代码与最新schema同步:

    npx prisma generate
    
  2. 确认数据库允许手动插入自增ID
    对于MySQL,自增字段默认支持手动插入,但可临时执行SQL调整模式,确保能插入指定ID:

    SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
    

    迁移完成后可恢复原有配置。

  3. 改用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"
      }
    })
    
  4. 检查枚举定义完整性
    确保ConfigItemType和ConfigItemStorageType已在schema中正确定义,且已生成到客户端。枚举定义缺失或不完整可能引发客户端解析异常,间接导致字段识别错误。


内容的提问来源于stack exchange,提问作者Boardy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:17:04