Skip to content

Multiple Connections / Databases / Datasources #2443

@FredericLatour

Description

@FredericLatour

Problem

An application may need to access different connections/databases.
One use case could be having the exact same set of tables into different databases (multi-tenant approach).
Another use case could be having to access punctually some specific data in a separate database/server.

In any cases "a single connection" for the entire application is a really strong limitation.
Any SQL driver or ORM is capable of connecting to multiple databases either by direct support (TypeOrm) or by creating 2 instances. Unless I missed something this is not possible with Prisma client.

Suggested solution

I believe that it can be easily achieved with the following approach that does not change much both on the schema and client side of things.

datasource proj01 {
  provider = "postgresql"
  url      = env("DATABASE_URL_PROJ01")
  models = [Post, User]
}

datasource proj02 {
  provider = "postgresql"
  url      = env("DATABASE_URL_PROJ02")
  models = [Post, User]
}

datasource common {
  provider = "postgresql"
  url      = env("DATABASE_URL_COMMON")
  models = [Config]
}


generator client {
  provider = "prisma-client-js"
}
model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  author    User?   @relation(fields:  [authorId], references: [id])
  authorId  Int?
}
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Config {
  id    Int     @id @default(autoincrement())
  field string
}

You would then need to make it possible to use one connection/db or another:

import { PrismaClient } from '@prisma/client'
const proj01= new PrismaClient('proj01')
const proj02= new PrismaClient('proj02')
const proj01Users = await proj01.user.findMany()
const proj02Users = await proj02.user.findMany()

Additional context

Please note that it has nothing to do with having a dynamic url for being able to point to a different database when in development and/or staging. This feature is also needed but it's a different matter.
Note also that this is not exclusively to solve "multi-tenant" scenarios. I may need to access a database on another server whatever the reason.

Update 01: different database per environment use case

Thinking a bit more about it, this feature also provides a solution to the problem of having a different database (sqlite vs other database in prod for instance) depending on the environment (prod, staging, dev).

Adding on my previous example, you could have :

datasource proj01 {
  provider = "postgresql"
  url      = env("DATABASE_URL_PROJ01")
  models = [Post, User]
}

datasource proj01-dev {
  provider = "sqlitel"
  url      = env("DATABASE_URL_PROJ01")
  models = [Post, User]
}

And then depending on the environment:

import { PrismaClient } from '@prisma/client'
const proj01 = ( process.env.NODE_ENV === 'prod')  ? 
                            new PrismaClient('proj01')  :
                            new PrismaClient('proj01-dev')

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions