Prisma的findUnique方法中只接受一个唯一参数。

11

我遇到了一个问题,需要通过用户名和电子邮件检查用户是否存在,因为两者都是数据库中的唯一字段,但我遇到了一个错误。Argument where of type UserWhereUniqueInput needs exactly one argument, but you provided username and email. Please choose one.所以,有没有一种方法可以只执行一次此查询?而不是像以下那样每个字段运行一次查询。

const user = await prisma.user.findUnique({
        where: {
          username,
          email,
        },
      });

而不是像这样

const user = await prisma.user.findUnique({
        where: {
          username,
        },
      });

const user = await prisma.user.findUnique({
        where: {
          email,
        },
      });


1
你的 User 模型中,usernameemail 是否都是必填项,或者其中一个在 Prisma schema 中被标记为可选项,带有 ? 符号? - nburk
5个回答

13

如果你想要一个能够帮你得到单一结果的独特值,你也可以使用findFirst。它会返回一个对象而不是数组。即使你在寻找唯一值,findMany也会返回一个数组。

const users = await prisma.user.findFirst({
 where: {OR: [{username},{email}]}
});

我还是不知道为什么这对我行不通。我正在按照这个方法做,但却收到“PrismaClientValidationError”的错误。我尝试了chatgpt、bard、google,似乎没有人知道为什么这不起作用的解决办法。 - Korovjov

6

我不完全确定,但prisma返回一个JS对象...所以这样的查询应该是有效的:

const query = await prisma.user.findUnique({
        where: {
          user: user.username
        },
       select: {
         user: true,
         email: true
      }
      });

我认为这应该能工作,但它仍只按一个唯一的方式查找。我不确定为什么您会将用户+电子邮件都选择为唯一项,因为我认为其中一个与另一个有关系。
如果我的解决方案无法工作,请参考此处以获取更多答案:https://www.prisma.io/docs/concepts/components/prisma-client/crud#findfirst

4
我是Prisma团队的Nikolas。我认为select关键字并没有影响,但这很重要:“我不确定你为什么会选择将用户和电子邮件都作为唯一标识,因为我认为其中一个与另一个已经绑定了。”由于idemail都是唯一属性,因此在findUnique查询中提供两者之一就足够了,提供两者没有任何意义。@ahmdtalat,你应该只需使用其中一个即可得到相同的结果。 - nburk

6

从逻辑上讲,电子邮件是一个独特的字段(没有两个人共享相同的电子邮件)。用户名字段不是唯一的(多个用户具有相同的名称)。 下面的代码足以获取该唯一用户。

const user = await prisma.user.findUnique({
        where: {
          email
        },
      });

假设仅使用电子邮件或用户名无法唯一确定用户身份,但电子邮件和用户名的组合可以唯一确定用户身份。
请修改下面显示的模式。
model user {
  username : String
  email    : String
  @@unique([username, email])
}

现在您可以通过唯一的电子邮件和用户名进行查询,而无需提供多个where参数

   const user = await prisma.findUnique({
        where: {
          username_email : { username, email },
        },
      });

参考文献:


我同意从逻辑上讲,我们都应该拥有独一无二的电子邮件地址,除非我们在谈论公司。比如说你在xy公司工作,你叫约翰·多伊。你被解雇了,你的电子邮件地址就被删除了或者其他什么情况。然后另一个叫约翰·多伊的人来了,他得到了相同的电子邮件地址。这种情况也适用于政府等机构。所以,电子邮件的唯一性就不复存在了(我现在正在处理一个可能会遇到这个问题的项目)。 - Korovjov
@Korovjov 根据唯一标识进行查询。 - Hussam Khatib

0
const users = await prisma.user.findMany({
       where: {
        OR: [
          {username},
          {email}
        ]
      }
  });
 if (users.length !== 0) {...}

0
我用这个来进行登录,并使用bcrypt比较密码,这是我所做的一个示例。
const customerSignIn = async (req, res) => {
  const { email } = req.body
  try {
    const getUser = await customers.findUnique({
      where: { email },
      select: {
        email: true,
        password: true,
      },
    }) || null
    console.log(getUser)
    const compare = await comparePassword(req.body.password, getUser.password)
    console.log(compare)
    // getUser && getUser.password === req.body.password ? ....
    getUser && compare ? res.json({....

这份工作对我来说很好!你可以检查并使用它。 没问题,你也可以在这里找到密码。
const { email, password } = req.body

然后将其传递给comparePassword方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接