如何将 Prisma ORM 与多个数据库模式一起使用
PostgreSQL、CockroachDB 和 SQL Server 连接器目前支持多数据库模式。
许多数据库提供商允许您将数据库表组织成命名的组。您可以使用它来使数据模型的逻辑结构更易于理解,或避免表之间的命名冲突。
在 PostgreSQL、CockroachDB 和 SQL Server 中,这些组被称为模式(schemas)。我们将它们称为数据库模式,以区分于 Prisma ORM 自身的 schema。
本指南将解释如何
- 在您的 Prisma schema 中包含多个数据库模式
- 使用 Prisma Migrate 和 db push 将您的 schema 更改应用到数据库
- 内省具有多个数据库模式的现有数据库
- 使用 Prisma Client 跨多个数据库模式进行查询
如何启用 multiSchema 预览特性
多模式支持目前处于预览阶段。要启用 multiSchema 预览特性,请将 multiSchema 特性标志添加到 Prisma Schema 中 generator 块的 previewFeatures 字段。
generator client {
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
如何在您的 Prisma schema 中包含多个数据库模式
要在您的 Prisma schema 文件中使用多个数据库模式,请将您的数据库模式的名称添加到 datasource 块中 schemas 字段的数组中。以下示例添加了 "base" 和 "transactional" 模式
generator client {
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["base", "transactional"]
}
您无需更改您的连接字符串。您的连接字符串的 schema 值是 Prisma Client 连接并用于原始查询的默认数据库模式。所有其他 Prisma Client 查询都使用您正在查询的模型或枚举的模式。
要指定模型或枚举属于特定的数据库模式,请添加 @@schema 属性,并将数据库模式的名称作为参数。在以下示例中,User 模型是 "base" 模式的一部分,而 Order 模型和 Size 枚举是 "transactional" 模式的一部分
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 schema 中将表名映射到唯一的模型名称。这避免了在 Prisma Client 中查询模型时出现名称冲突。
例如,考虑这样一种情况:base 数据库模式中的 config 表与 users 数据库模式中的 config 表同名。为避免名称冲突,请在您的 Prisma schema 中为模型指定唯一的名称 (BaseConfig 和 UserConfig),并使用 @@map 属性将每个模型映射到相应的表名
model BaseConfig {
id Int @id
@@map("config")
@@schema("base")
}
model UserConfig {
id Int @id
@@map("config")
@@schema("users")
}
如何使用 Prisma Migrate 和 db push 应用您的 schema 更改
您可以使用 Prisma Migrate 或 db push 将更改应用到具有多个数据库模式的 Prisma schema。
例如,将 Profile 模型添加到上面博客文章模型的 base 模式
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")
}
然后您可以将此 schema 更改应用到您的数据库。例如,您可以使用 migrate dev 创建迁移并应用您的 schema 更改
npx prisma migrate dev --name add_profile
请注意,如果您将模型或枚举从一个模式移动到另一个模式,Prisma ORM 会从源模式中删除该模型或枚举,并在目标模式中创建一个新的模型或枚举。
如何内省具有多个数据库模式的现有数据库
您可以使用 db pull 内省具有多个数据库模式的现有数据库,就像内省具有单个数据库模式的数据库一样
npx prisma db pull
这将更新您的 Prisma schema 以匹配数据库的当前状态。
如果您在不同的数据库模式中有名称相同的表,Prisma ORM 会显示一个验证错误,指出冲突。要解决此问题,请使用 @map 属性重命名内省的模型。
如何使用 Prisma Client 跨多个数据库模式进行查询
您可以在多个数据库模式中查询模型,而无需更改 Prisma Client 查询语法。例如,以下查询使用上面的 Prisma schema 查找给定用户的所有订单
const orders = await prisma.order.findMany({
where: {
user: {
id: 1,
},
},
})
了解有关 multiSchema 预览特性的更多信息
要了解有关 multiSchema 预览特性的未来计划或提供反馈,请参阅我们的 Github issue。our Github issue.