跳至主要内容

如何在 Prisma ORM 中使用多个数据库模式

警告

多个数据库模式支持目前可用于 PostgreSQL、CockroachDB 和 SQL Server 连接器。

许多数据库提供商允许您将数据库表组织到命名组中。您可以使用它来使数据模型的逻辑结构更易于理解,或者避免表之间的命名冲突。

在 PostgreSQL、CockroachDB 和 SQL Server 中,这些组被称为模式。我们将称之为_数据库模式_,以区别于 Prisma ORM 自己的模式。

本指南介绍如何

  • 在您的 Prisma 架构中包含多个数据库模式
  • 使用 Prisma Migrate 和 db push 将您的架构更改应用于您的数据库
  • 内省具有多个数据库模式的现有数据库
  • 使用 Prisma 客户端跨多个数据库模式进行查询

如何启用 multiSchema 预览功能

多模式支持目前处于预览状态。要启用 multiSchema 预览功能,请将 multiSchema 功能标志添加到 Prisma 架构中 generator 块的 previewFeatures 字段

schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

如何在 Prisma 架构中包含多个数据库模式

要在 Prisma 架构文件中使用多个数据库模式,请将数据库模式的名称添加到 datasource 块中 schemas 字段的数组中。以下示例添加了 "base""transactional" 模式

schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["base", "transactional"]
}

您不需要更改连接字符串。连接字符串的 schema 值是 Prisma 客户端连接到的默认数据库模式,并用于原始查询。所有其他 Prisma 客户端查询使用您正在查询的模型或枚举的模式。

要指定模型或枚举属于特定数据库模式,请添加 @@schema 属性,并将数据库模式的名称作为参数。在以下示例中,User 模型是 "base" 模式的一部分,Order 模型和 Size 枚举是 "transactional" 模式的一部分

schema.prisma
model User {
id Int @id
orders Order[]

@@schema("base")
}

model Order {
id Int @id
user User @relation(fields: [id], references: [id])
user_id Int

@@schema("transactional")
}

enum Size {
Small
Medium
Large

@@schema("transactional")
}

不同数据库模式中具有相同名称的表

如果您的不同数据库模式中存在同名的表,您需要将表名映射到 Prisma 架构中的唯一模型名。这可以避免在您在 Prisma 客户端中查询模型时发生命名冲突。

例如,考虑这样一种情况:base 数据库模式中的 config 表与 users 数据库模式中的 config 表具有相同的名称。为了避免命名冲突,请在 Prisma 架构中为模型赋予唯一名称 (BaseConfigUserConfig),并使用 @@map 属性将每个模型映射到相应的表名

schema.prisma
model BaseConfig {
id Int @id

@@map("config")
@@schema("base")
}

model UserConfig {
id Int @id

@@map("config")
@@schema("users")
}

如何使用 Prisma Migrate 和 db push 应用您的架构更改

您可以使用 Prisma Migrate 或 db push 将更改应用于具有多个数据库模式的 Prisma 架构。

例如,在上面博客文章模型的 base 模式中添加一个 Profile 模型

schema.prisma
model User {
id Int @id
orders Order[]
profile Profile?

@@schema("base")
}

model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
userId Int @unique

@@schema("base")
}

model Order {
id Int @id
user User @relation(fields: [id], references: [id])
user_id Int

@@schema("transactional")
}

enum Size {
Small
Medium
Large

@@schema("transactional")
}

然后,您可以将此架构更改应用于您的数据库。例如,您可以使用 migrate dev 创建并应用您的架构更改作为迁移

npx prisma migrate dev --name add_profile

请注意,如果您将模型或枚举从一个模式移动到另一个模式,Prisma ORM 会从源模式中删除模型或枚举,并在目标模式中创建一个新的模型或枚举。

如何内省具有多个数据库模式的现有数据库

您可以内省具有多个数据库模式的现有数据库,方法与内省具有单个数据库模式的数据库相同,使用 db pull

npx prisma db pull

这会更新您的 Prisma 架构以匹配数据库的当前状态。

如果您在不同的数据库模式中存在同名的表,Prisma ORM 会显示一个验证错误,指出冲突。要解决此问题,使用 @map 属性重命名内省的模型

如何使用 Prisma 客户端跨多个数据库模式进行查询

您可以查询多个数据库模式中的模型,而无需对 Prisma 客户端查询语法进行任何更改。例如,以下查询使用上面所示的 Prisma 架构查找给定用户的全部订单

const orders = await prisma.order.findMany({
where: {
user: {
id: 1,
},
},
})

详细了解 multiSchema 预览功能

要详细了解 multiSchema 预览功能的未来计划,或提供反馈,请参阅 我们的 Github 问题