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

如何在Prisma 5.4.1中实现多字段唯一约束不区分大小写?

解决Prisma多字段联合唯一不区分大小写及更新查询校验问题

一、实现多字段联合唯一不区分大小写

Prisma 5.4.1版本的@@unique不支持直接配置caseInsensitive选项,可通过以下两种方案实现需求:

方案1:数据库层面创建不区分大小写的联合唯一约束

不同数据库的实现方式不同:

  • PostgreSQL:可启用citext类型(需先执行CREATE EXTENSION citext;),或直接基于字段小写值创建唯一索引:
    CREATE UNIQUE INDEX idx_unique_name_size_color ON "SomeModel" (lower(name), lower(size), lower(color));
    
  • MySQL:利用大小写不敏感的字符集(如utf8mb4_ci),或创建基于小写值的唯一索引:
    CREATE UNIQUE INDEX idx_unique_name_size_color ON SomeModel (LOWER(name), LOWER(size), LOWER(color));
    

数据库层面的约束会自动校验字段小写后的组合唯一性,无需修改Prisma模型结构。

方案2:在Prisma模型中新增小写字段并设置联合唯一

修改模型,自动生成原字段的小写映射字段,再对这些小写字段设置联合唯一:

model SomeModel {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  name      String 
  size      String 
  color     String

  // 新增小写字段,映射到数据库对应列
  nameLower String @map("name_lower")
  sizeLower String @map("size_lower")
  colorLower String @map("color_lower")

  // 对小写字段设置联合唯一
  @@unique([nameLower, sizeLower, colorLower])
}

需额外创建数据库触发器,确保原字段更新时小写字段同步更新为对应小写值,以PostgreSQL为例:

CREATE OR REPLACE FUNCTION update_lower_fields()
RETURNS TRIGGER AS $$
BEGIN
  NEW.name_lower = LOWER(NEW.name);
  NEW.size_lower = LOWER(NEW.size);
  NEW.color_lower = LOWER(NEW.color);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_update_lower_fields
BEFORE INSERT OR UPDATE ON "SomeModel"
FOR EACH ROW EXECUTE FUNCTION update_lower_fields();

二、修复更新查询时的不区分大小写校验错误

你遇到的错误是因为复合唯一约束的字段组合(如name_size_color)在where条件中仅支持传入字符串值,无法使用{equals: ..., mode: "insensitive"}这类过滤对象。需改用AND条件拼接每个字段的不区分大小写过滤逻辑:

await prisma.someModel.update({
  where: {
    uuid: "3790181d-c4f8-4832-94bb-22b969eafcf6",
    AND: [
      data.name !== undefined ? { name: { equals: data.name, mode: "insensitive" } } : {},
      data.size !== undefined ? { size: { equals: data.size, mode: "insensitive" } } : {},
      data.color !== undefined ? { color: { equals: data.color, mode: "insensitive" } } : {}
    ].filter(cond => Object.keys(cond).length > 0)
  },
  data: {
    quantity: { increment: 3 }
  }
});

该写法支持不区分大小写匹配,同时兼容null、空字符串及普通字符串的场景。若无需匹配uuid,直接保留AND条件即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:21:28