💽
Prismaで複数のデータベースを同時に扱う
はじめに
対象読者
- Prismaを使っている
- Node.jsを使っている(もしくは個別に変換して解釈できる)
- 複数のデータベースを同じプロジェクトで扱う必要がある
- とりあえず動かしたい
手順
- Prisma schemaの作成
- Prisma clientの生成
- Clientのインポート&初期化
- それぞれのクライアントを使う
Prisma schemaの作成
Prismaで複数のデータベースを同時に扱うには、Schemaを複数作成する必要があります。
また、generatorの設定にoutput
の項目を追加することで/prisma/generate
の中にそれぞれの名前でPrisma clientファイルが生成されます
serviceA.schema
datasource db {
provider = "postgresql"
url = env("DATABASE_URL_SERVICE_A")
}
generator client {
provider = "prisma-client-js"
output = "./generated/service_a"
}
model user {
id String @id
name String
}
serviceB.schema
datasource db {
provider = "postgresql"
url = env("DATABASE_URL_SERVICE_B")
}
generator client {
provider = "prisma-client-js"
output = "./generated/service_b"
}
model user {
id String @id
name String
}
Prisma clientの生成
普通にprisma.schema単体で使う場合はprisma generate
だけでもPrisma CLIが良しなにやってくれるのですが、複数のschemaファイルがある場合にはそれぞれを指定してあげる必要があります。
実際にクライアントを生成する
shell
$ # コマンド例
$ # prisma generate --schema {Schemaのパス}/{Schemaファイル名}
$
$ prisma generate --schema prisma/serviceA.prisma
$ prisma generate --schema prisma/serviceB.prisma
上記コマンドを実行すると/prisma/generated/
に生成されたそれぞれのデータベース用のクライアントが生成されます。
package.json
"scripts": {
....
"prisma:migrate:all": "npx pnpm migrate --schema prisma/own-auth.prisma --preview-feature && npx pnpm migrate --schema prisma/own-developer.prisma --preview-feature",
"prisma:generate:all": "prisma generate --schema prisma/own-auth.prisma && prisma generate --schema prisma/own-developer.prisma"
}
Clientのインポート&初期化
それぞれのクライアントを初期化する際にデータベースを指定してあげる必要があります。
prisma.ts
// それぞれのクライアントをインポート
import { PrismaClient as serviecA } from '@prisma/generated/own-auth-client'
import { PrismaClient as serviecB } from '@prisma/generated/own-developer-client'
import { PrismaClient } from '@prisma/client'
// クライアント生成時の例
// export const clientX = new serviecB({
// datasources: { db: { url: '{db_provider}://{db_url}/{table_name}' } },
// })
// ServiceAのクライアント生成
export const clientA = new serviecA({
datasources: { db: { url: 'postgres://localhost:5432/service_a' } },
})
// ServiceBのクライアント生成
export const clientB = new serviecB({
datasources: { db: { url: 'postgres://localhost:5432/service_b' } },
})
それぞれのクライアントを使う
serviceA, serviceBのデータベースに対してそれぞれのuserテーブルのデータをIDをキーにして検索&取得するコードの例です。
index.ts
import { clientA, clientB } from './prisma.ts'
export const findNameFromClientA = async (userId: string) => {
return await clientA.user.findUnique({
where: { id: userId },
})
}
export const findNameFromClientB = async (userId: string) => {
return await clientB.user.findUnique({
where: { id: userId },
})
}
Discussion