Prisma: 2.0.0-beta.1 Release

Release date:
March 31, 2020
Previous version:
Could not determine previous release version
Magnitude:
0 Diff Delta
Contributors:
0 total committers
Data confidence:
Commits:

Top Contributors in 2.0.0-beta.1

Could not determine top contributors for this release.

Directory Browser for 2.0.0-beta.1

We couldn't find a release before this one

Release Notes Published

We are extremely excited to launch the first official Beta of Prisma 2.0 today! πŸŽ‰ Along with this release, we have also published a new website and an updated Prisma 2.0 documentation. This makes Prisma 2.0 the default for developers who are getting started with Prisma.

Upgrading to the new relation syntax

If you have been using Prisma Migrate before to create your models and their relations, the new relation syntax can seem a bit counterintuitive at first. Here's a quick overview of the most important things to consider when upgrading.

Note that this only covers one-to-one and one-to-many relations. Prisma's implicit many-to-many relations are adjusted by manually adding the @relation attribute with a single field reference to both sides of the relation (most often this looks as follows: @relation(references: [id])).

Consider this sample schema from preview025:

model User {
  id      Int      @id @default(autoincrement())
  profile Profile?
  posts   Post[]
}

model Profile {
  id   Int  @id @default(autoincrement())
  user User // backed up by a foreign key called `user` in the DB   
}

model Post {
  id     Int  @id @default(autoincrement())
  author User // backed up by a foreign key called `author` in the DB   
}

<details><summary>Expand for the corresponding SQL</summary>

CREATE TABLE "User" (
    id integer PRIMARY KEY,
    name text NOT NULL DEFAULT ''::text
);

CREATE TABLE "Profile" (
    bio text NOT NULL DEFAULT ''::text,
    id integer PRIMARY KEY,
    user integer NOT NULL,
    FOREIGN KEY ("user") REFERENCES "User"(id)
);

CREATE TABLE "Post" (
    id integer PRIMARY KEY,
    title text NOT NULL
    author integer NOT NULL,
    FOREIGN KEY ("author") REFERENCES "User"(id)
);

</details>

Note that in this case, the foreign keys in the underlying database are located on the Profile and Post tables. The User table does not have any foreign keys (which means the profile and posts relation fields on the User model are virtually maintained by Prisma).

The new syntax requires you to make the foreign key explicit in the Prisma schema (so you need to add another field in addition to the already existing relation field). This new field is your relation scalar field and directly represents the foreign key in the underlying database.

Assume you're now upgrading to 2.0.0-beta.1:

npm install @prisma/[email protected]
npm install @prisma/[email protected] --save-dev

Without touching the database, one way to adjust your Prisma schema to adhere to the new syntax would be as follows:

model User {
  id      Int      @id @default(autoincrement())
  profile Profile?
}

model Profile {
  id      Int     @id @default(autoincrement())
  user    User    @relation(fields: [userId], references: [id])
+ userId  Int     @map("user") // relation scalar field (used in the `@relation` attribute above)
}

model Post {
  id         Int         @id @default(autoincrement())
  author     User        @relation(fields: [authorId], references: [id])
+ authorId   Int         @map("author") // relation scalar field  (used in the `@relation` attribute above)
}

In this code, you introduced the userId and authorId fields on Profile and Post. These fields are your relation scalar fields and represent the foreign key in your database. But because the current foreign keys in the database are called user and author and therefore don't map directly to the model fields, you need to annotate the fields with @map to "map" them to a differently named database column.

You can then re-generate Prisma Client. Note that the prisma2 command has been renamed to prisma in 2.0.0-beta.1, so you need to invoke the generate command as follows:

npx prisma generate

Note that the new relation scalar field is currently read-only in the generated Prisma Client API. To modify the connections in youe database, you can keep using Prisma Client's nested write queries.

Breaking changes

No more Preview releases

With this release the Preview period for Prisma 2.0 ends. This means that releases will not be tagged preview any more, but with beta. Today's release is called: 2.0.0-beta.1.

Restructuring GitHub repositories

Since its initial release, the main repository for Prisma 2.0 has been called prisma2.

Because Prisma 2.0 is now the default for developers getting started with Prisma, the Prisma repositories have been renamed as follows:

Renaming the prisma2 CLI

During the Preview period, the CLI for Prisma 2.0 was invoked using the prisma2 command. With Prisma 2.0 being the default for new developers getting started with Prisma, the command is changed to just prisma. The exising prisma command of Prisma 1 is renamed to prisma1.

Also note that the installation of the npm packages changes:

| Prisma version | Old CLI command | New CLI command | Old npm package name | New npm package name | | :------------- | :-------------- | :-------------- | :------------------- | :------------------- | | 2.0 | prisma2 | prisma | prisma2 | @prisma/cli | | 1.X | prisma | prisma1 | prisma | prisma1 |

New syntax for defining relations

The Beta release introduces a new relation syntax which makes the @relation attribute required in each relation in the Prisma schema. Note that it often is enough to only declare the attribute only on the side of the relation (the side that stores the foreign key in the underlying database).

Additionally, for one-to-one and one-to-many relations, you need add a relation scalar field to the model which is used in the @relation attribute. This relation scalar field directly maps to the foreign key in the underlying database. Note that the foreign key is read-only in the Prisma Client API, to modify a relation you can keep using nested write queries as before.

Here's an overview for how relations need to be updated.

One-to-one

During the Preview period, a 1-1-relation could be defined as follows:

model User {
  id        Int       @id @default(autoincrement())
  profile   Profile
}

model Profile {
  id      Int    @id @default(autoincrement())
  user    User
}

With the new Beta, you now must determine which side should store the foreign key. You can do so by adding the @relation attribute with its corresponding relation scalar field to the model:

model User {
  id        Int       @id @default(autoincrement())
  profile   Profile
}

model Profile {
  id      Int    @id @default(autoincrement())
+ user    User   @relation(fields: [userId], references: [id])
+ userId  Int    // relation scalar field (used in the `@relation` attribute above)
}

This Prisma schema is represented as follows in SQL (the foreign key is stored on Profile):

CREATE TABLE "User" (
    id SERIAL PRIMARY KEY
);
CREATE TABLE "Profile" (
    id SERIAL PRIMARY KEY,
    "userId" INTEGER NOT NULL UNIQUE,
    FOREIGN KEY ("userId") REFERENCES "User"(id)
);

One-to-many

During the Preview period, a 1-n-relation could be defined as follows:

model User {
  id        Int      @id @default(autoincrement())
  posts     Post[]
}

model Post {
  id        Int   @id @default(autoincrement())
  author    User
}

With the new Beta, you now must add the @relation attribute and its corresponding relation scalar field to the non-list field of the relation:

model User {
  id        Int      @id @default(autoincrement())
  posts     Post[]
}

model Post {
  id        Int   @id @default(autoincrement())
+ author    User  @relation(fields: [authorId], references: [id])
+ authorId  Int
}

This Prisma schema is represented as follows in SQL:

CREATE TABLE "User" (
    id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
    id SERIAL PRIMARY KEY,
    "authorId" integer NOT NULL,
    FOREIGN KEY ("authorId") REFERENCES "User"(id)
);

Many-to-many (implicit)

During the Preview period, a m-n-relation could be defined as follows:

model Post {
  id         Int        @id @default(autoincrement())
  categories Category[]
}

model Category {
  id    Int    @id @default(autoincrement())
  posts Post[]
}

With the new Beta, you now must add the @relation attribute to both sides of the relation:

model Post {
  id         Int        @id @default(autoincrement())
+ categories Category[] @relation(references: [id])
}

model Category {
  id    Int    @id @default(autoincrement())
+ posts Post[] @relation(references: [id])
}

Prisma will maintain the relation with the following relation table:

CREATE TABLE "Category" (
    id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
    id SERIAL PRIMARY KEY
);
-- Relation table + indexes -------------------------------------------------------
CREATE TABLE "_CategoryToPost" (
    "A" integer NOT NULL REFERENCES "Category"(id),
    "B" integer NOT NULL REFERENCES "Post"(id)
);
CREATE UNIQUE INDEX "_CategoryToPost_AB_unique" ON "_CategoryToPost"("A" int4_ops,"B" int4_ops);
CREATE INDEX "_CategoryToPost_B_index" ON "_CategoryToPost"("B" int4_ops);

Why this change was introduced

The changes in the relation syntax were needed to enable more complex relation configurations, e.g. when using multi-field IDs.

Note that we aim to simplify the current syntax in the future again ("take one step backward, to be able to move two steps forward").

The prisma2 npm package is deprecated

The prisma2 npm package is now deprecated, the Prisma 2.0 CLI can now be installed via the @prisma/cli npm package, e.g.:

npm @prisma/cli --save-dev
npx prisma

To prevent confusions during installation, it now outputs the following when you try to install it:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                             β”‚
β”‚   The package prisma2 has been renamed to @prisma/cli.      β”‚
β”‚                                                             β”‚
β”‚   Please uninstall prisma2 from your project or globally.   β”‚
β”‚   Then install @prisma/cli to continue using Prisma 2.0:    β”‚
β”‚                                                             β”‚
β”‚      # Uninstall old CLI                                    β”‚
β”‚      npm uninstall prisma2                                  β”‚
β”‚                                                             β”‚
β”‚      # Install new CLI                                      β”‚
β”‚      npm install @prisma/cli --save-dev                     β”‚
β”‚                                                             β”‚
β”‚      # Invoke via npx                                       β”‚
β”‚      npx prisma --help                                      β”‚
β”‚                                                             β”‚
β”‚   Learn more here: https://pris.ly/preview025               β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜