Multiple Prisma Clients, One App

There are times where you need to connect to multiple databases within a single backend server. I've found this is a lightly documented subject on the official Prisma docs, and wanted to make a quick guide for others.
I have been working on a GraphQL server that combines multiple internal datasets from our company, so it's crucial that I can easily query all of these different Postgres databases.
Initial Setup
In the top level of your app (where the package.json is located) install prisma like normal:
yarn add prisma @prisma/client
Next, create a new folder for every database you need to access. For example purposes we will make a folder called db1
and db2
In each folder, run the following:
npx prisma init
Next, open the prisma/schema.prisma
file, and make one change:
generator client {
provider = "prisma-client-js"
output = "../../src/generated/db1"
}
We are telling it to output the client into our src
folder at the root of the project, inside of a generated
folder. You should add this folder to .gitignore
so that it doesn't get committed. This change overrides the default output location, allowing us to import any number of prisma clients into our app.
Almost done!
Setup the .env
file, edit the schema however you'd like. In my use cases, I am adding the DATABASE_URL
to the .env, then running:
npx prisma db pull
This populates the schema with our existing structure.
Client Generation
In the top level package.json, I create a new script:
"generate": "cd db1 && npx prisma generate && cd ../db2 && npx prisma generate",
We need to go into each folder that we created above, and then run npx prisma generate
. Now, run yarn generate
to generate your clients.
Importing our Prisma Clients
I like to create a new file, src/db.ts
and do the following:
import { PrismaClient as DB1 } from "./generated/db1";
import { PrismaClient as DB2 } from "./generated/db2";
export const db1 = new DB1({
datasources: {
db: {
url: process.env.DB1_DATABASE_URL,
},
},
});
export const db2 = new DB2({
datasources: {
db: {
url: process.env.DB2_DATABASE_URL,
},
},
});
This is another important piece of setup, we must pass in the database connection strings to each of these, we can't rely on the .env
file inside of db1/.env
or db2/.env
.
Conclusion
That's all there is to it! You can now generate as many clients as you need for a single application. The most important steps are customizing the output paths of the client generation, and passing in the connection strings when you initialize the clients in your app.
If you have any questions about this approach please reach out to me on twitter