question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Deprecation of provider array notation

See original GitHub issue

TL;DR We recently realized that supporting an array of providers in the Prisma schema was premature, adding complexity in the process of improving the product (migrate, native types…), and causing some confusion about our intent.

We are deprecating its use and will consider another solution, better addressing how we want Prisma to support working with multiple databases in the future.

Context

On July 7th, we released Prisma 2.2.0, which came with the following feature: https://github.com/prisma/prisma/issues/1487

It allowed to define a provider using an array notation like:

datasource db {
  provider = ["sqlite", "postgres"]
  url = env("DATABASE_URL")
}

We want to deprecate this use and only allow a single provider per datasource.

Why are we doing this?

Our goal at Prisma is to make it approachable to work any database while ensuring people can make the most of them too.

Each database provider has their own strengths and weaknesses, making them fit certain use cases better than others. As an example, SQLite is great to easily get started anywhere but doesn’t scale in high-concurrency scenarios.

By allowing a Prisma data source to fit multiple providers, and leaving it up to the environment to decide which provider was active, we made it look like a single Prisma data source could work interchangeably with any of our supported database vendors, despite of their differences. This, in turn, restricts the set of functionalities one can use with their database.

This is not fully aligned with the goal mentioned above.

What we want is:

  • to make it easy to start developing using your database of choice (often SQLite as being the simplest for a lot of people) and make it possible to, when the time comes, switch to another database vendor while understanding the implication such a change will have on the schema, your data, and your code;
  • to enable developers making the most out of functionalities of their specific database provider, and not feel limited by using Prisma;
  • in the future, to make it simpler to have a single application using multiple data sources, each data source being possibly from a different provider.

I was using this! What should I do?

What will happen

In an upcoming release, Prisma will reject schemas that include multiple providers in a data source declaration.

We will communicate this date and update the issue once it’s defined. This issue is a heads up so we can let you know of the intent and you can prepare for it.

At that point, this means that the following will no longer be possible:

datasource db {
  provider = ["sqlite", "postgres"]
  url = env("DATABASE_URL")
}

Instead, Prisma will expect to have only a single provider listed:

datasource db {
  provider = "sqlite" // or "postgres"
  url = env("DATABASE_URL")
}

Implications

A situation where we’ve seen people using multiple providers for a single data source was when SQLite was used in their development environment while Postgres or MySQL was used in the staging/production environment.

This won’t be possible anymore after this change. Note that, while some projects have been famous for doing that, it is also generally considered more robust to align the providers across environments, as the tests will be consistent.

In situations where you started off an SQLite local database, we recommend installing a local instance of Postgres or MySQL on your local machine.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:64
  • Comments:24 (10 by maintainers)

github_iconTop GitHub Comments

12reactions
Bjoernstjernecommented, Nov 26, 2020

If you remove this, can we please use environment variable for provider instead? As @rhlsthrm said migrations would not work for us anymore.

7reactions
3dmindcommented, May 4, 2021

@DarkBitz A unit test should never depend on an external system like a database, in my opinion. To decouple unit tests from a database query I recommend the repository pattern. You define an abstract class with abstract methods for particular queries, like getUserById. Then you implement the repository twice:

The first one uses an in-memory data structure and is used in your unit tests. The second one uses the actual Prisma client.

You inject the in-memory repository into your unit tests and the Prisma repository into your production code.

Example: The abstract repository:

// user.repository.ts
abstract class UserRepository {
  abstract save(user: User): Promise<void>{}
  abstract getUserById(id: string): Promise<User>{}
}

The in-memory implementation:

// in-memory-user.repository.ts
@Injectable()
class InMemoryUserRepository extends UserRepository {
  private readonly users = new Map<string, User>()

  async save(user: User): Promise<void> {
    this.user.set(user.id, user);
  }

  async getUserById(id: string): Promise<User> {
    return this.users.get(id)
  }
}

Inject the in-memory repository in the unit test:

//...
const module: TestingModule = await Test.createTestingModule({
      providers: [
        {
          provide: UserRepository,
          useClass: InMemoryUserRepository,
        },
        //...
      ],
    }).compile();
//...

The Prisma repository:

// prism-user.repository.ts
@Injectable()
export class PrismaUserRepository extends UserRepository {
  constructor(private readonly prismaService: PrismaService) {
    super();
  }

  async save(user: User): Promise<void> {
    // Use actual Prisma query here.
  }

  async getUserById(id: string): Promise<User> {
    // Use actual Prisma query here.
  }
}

The provider for the Prisma repository

// user-repository.provider.ts
export const UserRepositoryProvider: Provider = {
  provide: UserRepository,
  useClass: PrismaUserRepository,
};

Load this provider when you would like to inject and use the actual Prisma repository. For example in a controller or service.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Final Class: ArrayDataProvider - Oracle
Object representing data available from an array or observableArray. ... Returns a string that indicates if this data provider is empty.
Read more >
Providing dependencies in modules - Angular
A provider is an instruction to the Dependency Injection system on how to obtain a value for a dependency. Most of the time,...
Read more >
PHP 8.1: New Features and Deprecations from the Major ...
An in-depth analysis of the newest PHP 8.1 release, including over 20 new features, changes, and deprecations in PHP 8.1.
Read more >
array - Maple Help - Maplesoft
Important: The array command has been deprecated. · An array is a specialization of a table, with zero or more specified dimensions, where...
Read more >
Details of the policy definition structure - Azure - Microsoft Learn
When a resource property field is an array, a special array alias can ... The Azure Policy service uses version , preview ,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found