如何在没有 ID 的情况下在 Prisma 中插入新记录?

Jos*_*ana 9 node.js prisma prisma-graphql

我使用 Prisma ( https://www.prisma.io ) 作为 ORM。我想在存储数据时检查重复项,如果不存在,则创建一个新记录。

我以为我可以使用 Prisma 提供的 upsert 方法来做到这一点,并且可以在生成的客户端中使用,但是该方法的 where 子句仅适用于 id(或 @unique 字段),但是如果记录不存在,则没有要提供的任何 ID。

我提供了一个问题的例子。

数据模型.prisma

type System {
  id: ID! @unique
  performances: [SystemPerformance!]! @relation(name: "PerformanceBySystem" onDelete: CASCADE)
  name: String! @unique
}

type SystemPerformance {
  id: ID! @unique
  system: System! @relation(name: "PerformanceBySystem")
  date: DateTime!
  perf1: Float
  perf2: Float
}
Run Code Online (Sandbox Code Playgroud)

种子.js

const { prisma } = require('./generated/prisma-client');
async function main(){
  await prisma.createSystem({
    name: 's1',
  });
  await prisma.createSystem({
    name: 's2',
  });
  await prisma.createSystem({
    name: 's3',
  });
}
main();
Run Code Online (Sandbox Code Playgroud)

创建后有一个包含三个系统的数据库,没有性能。如果没有任何具有相同日期和相同系统的系统,我正在尝试插入一个新的 SystemPerformance。我试过了

const { prisma } = require('./prisma/generated/prisma-client');

const perf = await prisma.upsertSystemPerformance({
       where: {
         system: {name: 's1'},
         date: "2019-03-12T00:01:06.000Z"
       },
       update: {
         perf1: 13.45,
         perf2: 18.93
       },
       create: {
        system: {
            connect: { name: 's1' }
        },
        date: "2019-03-12T00:01:06.000Z",
        perf1: 13.45,
        perf2: 18.93
       }
})

Run Code Online (Sandbox Code Playgroud)

但是抛出了一个异常:

UnhandledPromiseRejectionWarning: 错误:“SystemPerformanceWhereUniqueInput!”类型的变量“$where”预期值 但得到:{"system":{"name":'s1'},"date":"2019-03-12T00:01:06.000Z"}。原因:“系统”字段“系统”未在输入类型“SystemPerformanceWhereUniqueInput”中定义

我找到的唯一解决方案是检查是否存在,然后更新或创建,但我想用 upsert 来完成。

let check = await prisma.$exists.SystemPerformance({
            system: {name: 's1'},
            date: "2019-03-12T00:01:06.000Z"
        });
let perfo;
if (check){
  const sysPerf = await prisma.systemPerformances({where:{system: {name: 's1'}, date: "2019-03-12T00:01:06.000Z"}})
            .$fragment(`
            {
                id
            }
            `);
  perfo = await prisma.updateSystemPerformance({
    where: {id: sysPerf[0].id},
            data: {
              perf1: 13.45,
              perf2: 18.93
            }
   })
}
else {
  perfo = await prisma.createSystemPerformance({
    system: {
      connect: { name: 's1' }
    },
    date: "2019-03-12T00:01:06.000Z",
    perf1: 13.45,
    perf2: 18.93
  }
})
Run Code Online (Sandbox Code Playgroud)

有没有办法用 upsert 做到这一点?

Gav*_*vin 13

如果您仍然在这里没有答案,我使用了 @Antoine 的答案和另一个 SO 答案的组合:

model Likes {
  id         String     @id @unique @default(uuid())
  user_id    String
  tag        String
  auth_user  AuthUser   @relation(references: [id], fields: [user_id], onDelete: Cascade)

  @@unique([user_id, tag], name: "user_id_tag")  // <-- this is the unique constraint
  @@index([user_id])
  @@map("likes")
}
Run Code Online (Sandbox Code Playgroud)

然后我可以通过以下方式更新插入:

prisma.likes.upsert({
    where: {
        user_id_tag: { // <-- And this bit is important
            user_id: user.userId,
            tag: tag.tag
        }
    },
    update: {},
    create: tag
})
Run Code Online (Sandbox Code Playgroud)


Ant*_*ine 8

中的字段where必须是唯一的。

如果您可以创建一些字段,例如date@unique ( date: DateTime! @unique),并将其用于 upsert 中的位置,我认为它会起作用(在我的本地测试)