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

使用Prisma createMany()自动创建分期关联记录时出现500错误

问题描述

我使用Next.js、TypeScript、Prisma ORM与SQLite开发一款简易财务管控应用,包含Transaction(交易)和Installment(分期)两个数据模型。期望创建交易记录时自动生成对应的分期记录,原本计划通过Prisma的createMany()方法实现,但提交交易时出现500错误。代码经ESLint检测无语法/类型错误,console.log输出显示transaction与installments数据格式正确,但Prisma报错提示createMany为未知参数。

相关代码

schema.prisma

// schema.prisma
model Transaction {
  id                   String        @id @default(uuid())
  userId               String
  title                String
  description          String?
  category             String
  value                Float
  cardFlag             String
  paymentMethod        String
  installmentsQuantity Int?
  date                 DateTime
  cardIsClosed         Boolean?
  installments         Installment[]
}

model Installment {
  id            String      @id @default(uuid())
  date          DateTime
  value         Float
  transaction   Transaction @relation(fields: [transactionId], references: [id])
  transactionId String
}

/api/transactions/route.ts

// /api/transactions/route.ts
export async function POST(request: Request) {
  try {
    const transaction = await request.json()

    let installments: { date: Date; value: number }[] = []

    if (transaction.paymentMethod === 'Crédito') {
      const installmentsValue =
        transaction.value / transaction.installmentsQuantity

      installments = Array.from(
        { length: transaction.installmentsQuantity },
        () => {
          return {
            date: transaction.date,
            value: installmentsValue
          }
        }
      )
    }

    console.log(installments)
    console.log(transaction)

    const newTransaction = await prisma.transaction.create({
      data: {
        ...transaction,
        installment: {
          createMany: {
            data: installments
          }
        }
      },
      include: {
        installments: true
      }
    })

    return new NextResponse(JSON.stringify(newTransaction), {
      status: 201,
      headers: { 'Content-Type': 'application/json' }
    })
  } catch (error: any) {
    if (error.code === 'P2002') {
      return new NextResponse(JSON.stringify('Transaction already exists'), {
        status: 409
      })
    }

    return new NextResponse(error.message, { status: 500 })
  }
}

控制台输出

[
  { date: '2023-10-10T00:00:00.000Z', value: 100 },
  { date: '2023-10-10T00:00:00.000Z', value: 100 },
  { date: '2023-10-10T00:00:00.000Z', value: 100 }
]
{
  title: 'Test',
  description: '',
  category: 'Mercado',
  value: 300,
  paymentMethod: 'Crédito',
  cardFlag: 'Visa',
  installmentsQuantity: 3,
  date: '2023-10-10T00:00:00.000Z',
  userId: 'user_2WEVdNNOMsHXAC3u91fGyS1gJsC'
}

错误提示(中文翻译)

"无效的 `prisma.transaction.create()` 调用:

{
   data: {
     title: "Test",
     description: "",
     category: "Food",
     value: 200,
     paymentMethod: "Credit",
     cardFlag: "Visa",
     installmentsQuantity: 2,
     date: "2023-10-10T00:00:00.000Z",
     userId: "user_2WEVdNNOMsHXAC3u91fGyS1gJsC",
     installments: {
       createMany: {
       ~~~~~~~~~~
         data: [
           {
             date: "2023-10-10T00:00:00.000Z",
             value: 100
           },
           {
             date: "2023-10-10T00:00:00.000Z",
             value: 100
           }
         ]
       },
? create?: InstallmentCreateWithoutTransactionInput | InstallmentCreateWithoutTransactionInput[] | InstallmentUncheckedCreateWithoutTransactionInput | InstallmentUncheckedCreateWithoutTransactionInput[],
? connectOrCreate?: InstallmentCreateOrConnectWithoutTransactionInput | InstallmentCreateOrConnectWithoutTransactionInput[],
? connect?: InstallmentWhereUniqueInput | InstallmentWhereUniqueInput[]
     }
   },
   include: {
     installments: true
   }
}

未知参数 `createMany`。可用选项已在绿色部分列出。"
问题修复

核心问题

  1. 字段名拼写错误:代码中使用了单数installment,但模型中关联字段是复数installments,这是触发错误的直接原因。
  2. 嵌套创建语法限制:Prisma的嵌套关联创建中,多数版本不支持直接使用createMany,正确批量创建关联记录的方式是使用create并传入数组。

修复后的代码

// /api/transactions/route.ts
export async function POST(request: Request) {
  try {
    const transaction = await request.json()

    let installments: { date: string; value: number }[] = []

    if (transaction.paymentMethod === 'Crédito') {
      const installmentsValue = transaction.value / transaction.installmentsQuantity
      const baseDate = new Date(transaction.date)

      // 优化:分期日期按月递增,避免所有分期日期相同
      installments = Array.from({ length: transaction.installmentsQuantity }, (_, index) => {
        const installmentDate = new Date(baseDate)
        installmentDate.setMonth(baseDate.getMonth() + index)
        return {
          date: installmentDate.toISOString(),
          value: installmentsValue
        }
      })
    }

    const newTransaction = await prisma.transaction.create({
      data: {
        ...transaction,
        installments: { // 修正为复数字段名
          create: installments // 使用create+数组批量创建
        }
      },
      include: {
        installments: true
      }
    })

    return new NextResponse(JSON.stringify(newTransaction), {
      status: 201,
      headers: { 'Content-Type': 'application/json' }
    })
  } catch (error: any) {
    if (error.code === 'P2002') {
      return new NextResponse(JSON.stringify('交易记录已存在'), {
        status: 409
      })
    }

    return new NextResponse(error.message, { status: 500 })
  }
}

额外说明

若使用Prisma v4.16及以上版本,确实支持在嵌套关联中使用createMany,但需保证字段名正确(复数installments),语法如下:

installments: {
  createMany: {
    data: installments
  }
}

不过create+数组的写法兼容性更强,适合大多数场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:02:56