Prisma-multi-tenant uses a "management" datasource in order to keep track of all the tenants of your application.
Thanks to this management datasource, prisma-multi-tenant is able to migrate all your tenants at once, as well as providing you with a simple way to access the data of whichever tenant you want.
Prisma-multi-tenant is a two-part project:
- The CLI (
prisma-multi-tenant
) that you will use to init, develop, and deploy your tenants - The Client (
@prisma-multi-tenant/client
) that you will use in your app to access the data in your tenants
There are also plugins for Prisma-powered frameworks:
- The Blitz plugin (
@prisma-multi-tenant/blitz
) which adds multi-tenancy to your Blitz application. - The Redwood plugin (
@prisma-multi-tenant/redwood
) which adds multi-tenancy to your Redwood application.
Table of content:
Note: You can run the CLI with either
prisma-multi-tenant
orpmt
. Example:pmt init
Init multi-tenancy for your application
Options
Name | Type | Description |
---|---|---|
url | String | URL of the management database |
schema | String | Specify path of schema |
no-example | Boolean | Disable creation of example file |
Examples
prisma-multi-tenant init
prisma-multi-tenant init --url=file:management.db
prisma-multi-tenant init --schema db/schema.prisma
Explanations
The init
command is used to initialize your application to use prisma-multi-tenant
. It will do the following:
- Install
@prisma-multi-tenant/client
locally in your app - Prompt for the management datasource url
- Update the
prisma/.env
file with the management's url - Generate PrismaClient (for tenants & management)
- Set up the management datasource
- Create first tenant based on the
DATABASE_URL
env variable - Create an example script (
multi-tenancy-example.js
)
Note: Make sure you are using
DATABASE_URL
in the default datasource of your schema.prisma file
List all tenants
Options
Name | Type | Description |
---|---|---|
json | Boolean | Print using JSON Format |
Examples
prisma-multi-tenant list
prisma-multi-tenant list --json
Explanations
The list
command connects to the management datasource and returns all the tenants in it. You can use the --json
argument to retrieve a machine-readable format of your tenants for any use case you want.
Create a new tenant or management
Arguments
Name | Optional | Description |
---|---|---|
management | Yes | Create a new management |
Options
Name | Type | Description |
---|---|---|
name | String | Name of the tenant |
url | String | URL of the database |
schema | String | Specify path of schema |
no-management | Boolean | The new tenant will not be registered in the management database |
Examples
prisma-multi-tenant new
prisma-multi-tenant new --name=company_b --url=postgres://...
prisma-multi-tenant new --no-management
prisma-multi-tenant new management
Explanations
The new
command create a new database using your schema. It will use a name, and an url (that you can provide as options).
If you want to create a tenant without tracking it in the management datasource, you can use --no-management
. However be careful, because you will need to manually migrate up and down this tenant after that.
If you add the management
argument, you can create a new management database. If you want to use this new management, don't forget to add the url in the prisma/.env
file.
Use Studio to access a tenant
Arguments
Name | Optional | Description |
---|---|---|
name | No | Name of the tenant you want to access |
Options
Name | Type | Description |
---|---|---|
port | Number | Port to start Studio on |
schema | String | Specify path of schema |
Examples
prisma-multi-tenant studio your_tenant_name
prisma-multi-tenant studio your_other_tenant --port=5556
Explanations
The studio
command will connect to the management datasource to retrieve the url of the tenant given as an argument. If you want to run multiple studios, you can pass a specific --port
option.
Migrate up, down, or save tenants.
Note: You can also migrate up the management datasource to deploy another management database:
prisma-multi-tenant migrate management up -- --create-db
Arguments
Name | Optional | Description |
---|---|---|
name | Yes | Name of the tenant you want to migrate |
action | No | Migrate up , down , or save the tenant |
Options
Name | Type | Description |
---|---|---|
schema | String | Specify path of schema |
Examples
prisma-multi-tenant migrate your_tenant_name down
prisma-multi-tenant migrate up
prisma-multi-tenant migrate save
prisma-multi-tenant migrate your_other_tenant up -- --auto-approve
prisma-multi-tenant migrate management up -- --create-db
Explanations
The migrate
command is a wrapper to the @prisma/cli migrate
command. If you pass the name
argument, it will migrate a single tenant. Otherwise, it will apply the action to all of the tenants registered in the management datasource.
Any arguments written after --
will be passed to @prisma/cli migrate
.
The save
action will use the default DATABASE_URL value if no name
argument is given.
Delete one tenant
Arguments
Name | Optional | Description |
---|---|---|
name | No | Name of the tenant you want to delete |
Options
Name | Type | Description |
---|---|---|
schema | String | Specify path of schema |
force | Boolean | If true, will not ask for confirmation |
Examples
prisma-multi-tenant delete your_other_tenant
prisma-multi-tenant delete your_other_tenant --force
Explanations
The delete
command will migrate down the tenant datasource and unregister it from the management datasource.
Generate Prisma Clients for the tenants and management
Options
Name | Type | Description |
---|---|---|
schema | String | Specify path of schema |
watch | Boolean | Watches the Prisma project file |
Examples
prisma-multi-tenant generate
prisma-multi-tenant generate --watch
Explanations
The generate
command generates the Prisma Client package for both Tenants and Management.
Set env variables for a specific tenant
Arguments
Name | Optional | Description |
---|---|---|
name | No | Name of the tenant you want in your env |
Examples
prisma-multi-tenant env your_tenant_name -- npx @prisma/cli migrate save --experimental
Explanations
The env
command uses management to add the URL of your tenant in the DATABASE_URL
env variable. Because of that, you can use any @prisma/cli
command you want and it will use the tenant you specified.
Eject prisma-multi-tenant from your application
Explanations
The eject
command can be used if you no longer need prisma-multi-tenant
in your application. This command will uninstall @prisma-multi-tenant/client
. It will not touch your databases as you may have important data in them.
Displays the global help
Example
prisma-multi-tenant help
Note: The client will try to read the
MANAGEMENT_URL
environment variables inprisma/.env
, but you can also provide it yourself.
Constructor of the MultiTenant
class.
Usage (JavaScript)
const { MultiTenant } = require('@prisma-multi-tenant/client')
const multiTenant = new MultiTenant()
Usage (TypeScript)
This will give you autocompletion on your tenants
const { PrismaClient } = require('@prisma/client')
const { MultiTenant } = require('@prisma-multi-tenant/client')
const multiTenant = new MultiTenant<PrismaClient>()
No management
If you do not want to connect to the Management database when connecting to a new Tenant, you can add the useManagement: false
option:
const multiTenant = new MultiTenant({
useManagement: false,
})
Returns the PrismaClient of your tenant. Any options passed as second argument will be given to the PrismaClient constructor.
If the tenant is present in the local cache, this method will return it. Otherwise, if the useManagement
constructor's option is set to true
, it will try to find the tenant in the management database.
If the tenant couldn't be accessed (either because useManagement: false
or because it doesn't exist), this method will throw an error.
Usage
const prisma = await multiTenant.get('your_tenant_name')
const users = await prisma.users.findMany()
console.log(users)
Returns the PrismaClient of your tenant. Any options passed as second argument will be given to the PrismaClient constructor.
This method does not connect to management.
Usage
const prisma = await multiTenant.directGet({
name: 'your_other_tenant',
url: 'file:something.db',
})
const users = await prisma.user.findMany()
console.log(users)
Creates a new tenant in management and returns the corresponding PrismaClient. Any options passed as second argument will be given to the PrismaClient constructor.
This method will migrate up the new database to be up-to-date with the migrations.
Usage
const prisma = await multiTenant.createTenant({
name: 'a_new_tenant',
url: 'postgresql://the_postgres_url',
})
const users = await prisma.user.findMany()
console.log(users)
Delete a tenant in management.
This method will migrate down the database.
Usage
await multiTenant.deleteTenant('my_tenant')
Test if a tenant exists in management.
Usage
await multiTenant.existsTenant('my_tenant')
Disconnects all PrismaClient instances (management & tenants)
Usage
await multiTenant.disconnect()
Registers the middleware into Blitz. The tenantRouter
function is required, and you can also provide prismaOptions
to be passed to every Prisma Client instances used for the tenants.
Usage
In the blitz.config.js
file:
const { multiTenantMiddleware } = require('@prisma-multi-tenant/blitz')
module.exports = {
// ...
middleware: [
multiTenantMiddleware((req, res) => {
// The name can come from anywhere (headers, token, ...)
return 'my_tenant_A'
}),
],
}
Dynamically return the Prisma Client instance from the context. This replaces the generated code from Redwood.
Usage
In the api/src/lib/db.js
file:
import { MultiTenant, fromContext } from '@prisma-multi-tenant/redwood'
export const multiTenant = new MultiTenant()
export const db = fromContext()
Everywhere else:
import { db } from 'src/lib/db'
//
db.post.findMany()