Overview

This upgrade guide describes how to migrate a Node.js project that's based on Prisma 1 and uses the Prisma client to Prisma 2.

Note: During the upgrade process it can be helpful to get a graphical view on your database. It is therefore recommended to use a graphical database client to connect to your database, such as TablePlus or Postico.

Main differences between Prisma 1 and Prisma 2.0

On a high-level, the biggest differences between Prisma 1 and Prisma 2.0 are the following:

  • Prisma 2.0 doesn't require hosting a database proxy server (i.e., the Prisma server).
  • Prisma 2.0 makes the features of Prisma 1 more modular and splits them into dedicated tools:
    • Prisma Client: An improved version of Prisma client 1.0
    • Prisma Migrate: Data modeling and migrations (formerly prisma deploy).
  • Prisma 1 datamodel and prisma.yml have been merged into the Prisma schema.
  • Prisma 2.0 uses its own modeling language instead of being based on GraphQL SDL.
  • Prisma 2.0 doesn't expose "a GraphQL API for your database" anymore, but only allows for programmatic access via the Prisma Client API.
  • More powerful introspection allows connecting Prisma 2.0 to any existing database.

Based on these differences, the high-level steps to upgrade a project from using Prisma 1 are as follows:

  1. Install the new Prisma 2.0 CLI as a development dependency
  2. Use the Prisma 2.0 CLI to introspect your Prisma 1 database and generate your Prisma schema
  3. Install and generate Prisma Client 2.0
  4. Adjust your application code, specifically replace the API calls from the Prisma client 1.0 with those of Prisma Client 2.0

Note that steps 3. and 4. will look somewhat different if you are:

  • not using the Prisma client (e.g. because you're using Prisma bindings).
  • building a GraphQL API using nexus-prisma.

Both scenarios will be covered in other upgrade guides that are coming soon.

In this guide, we'll take a look at migrating a REST API from Prisma 1 to Prisma 2.0 based on this Prisma 1 example.

Note: If you're upgrading a project that uses nexus-prisma, be sure to check out Robert Cooper's upgrade guide as well as Ahmed Elywa's project create-nexus-type that converts Prisma models into Nexus objectType definitions.

1. Install Prisma 2.0 CLI

The Prisma 2.0 CLI is available as the @prisma/cli package on npm and is invoked via the prisma command.

Note that the former prisma command for Prisma 1 has been renamed to prisma1. You can learn more about this here.

You can install the Prisma 2.0 CLI in your Node.js project as follows (be sure to invoke this command in the directory where your package.json is located):

npm install @prisma/cli --save-dev

Note: With Prisma 1, it was usually recommended to install the CLI globally. We now recommend to install the Prisma CLI locally to prevent version conflicts.

You can now use the local installation of the prisma CLI by prefixing it with npx:

npx prisma

2. Introspect your database to generate the Prisma 2.0 data model

The Prisma schema is the foundation for any project that uses Prisma 2.0. Think of the Prisma schema as the combination of the Prisma 1 data model and prisma.yml configuration file.

2.1. Create your Prisma schema file

For this guide, you'll first create a new Prisma schema using the prisma init command and then "fill" it with a data model using introspection.

Run the following command to create your Prisma schema:

npx prisma init

If you're seeing the following error, you need to rename your current prisma directory:

$ npx prisma init
ERROR A folder called prisma already exists in your project.
Please try again in a project that is not yet using Prisma.

You can rename the current prisma directory to prisma1 to make it clear that this holds the former Prisma 1 configuration:

mv prisma prisma1

Now you can run init and it will succeed:

npx prisma init

It should print the following output:

$ npx prisma init
✔ Your Prisma schema was created at prisma/schema.prisma.
You can now open it in your favorite editor.
Next steps:
1. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql or sqlite.
2. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started.
3. Run prisma introspect to turn your database schema into a Prisma data model.
4. Run prisma generate to install Prisma Client. You can then start querying your database.
More information in our documentation:
https://pris.ly/d/getting-started

The command created a new folder called prisma with two files:

Your initial Prisma schema looks as follows:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}

With Prisma 1, you specify which language variant of the Prisma client you wanted to use in your prisma.yml. With Prisma 2.0, this information is now also contained inside the Prisma schema via a generator block.

Note: Unlike Prisma 1, the TypeScript and JavaScript variants of Prisma Client 2.0 use the same generator called prisma-client-js. The generated types in index.d.ts are always included, even in plain JavaScript projects. This enables feature like autocompletion in VS Code even when not using TypeScript.

2.2. Set your database connection URL

With Prisma 1, the database connection is configured in the Docker Compose file that's used to launch the Prisma server. The Prisma server then exposes a GraphQL endpoint (via HTTP) that proxies all database requests from the Prisma client application code. That HTTP endpoint is specified in your prisma.yml.

With Prisma 2.0, the HTTP layer isn't exposed any more and Prisma Client 2.0 is configured to run requests "directly" against the database (that is, requests are proxied by Prisma's query engine, but there isn't an extra server any more).

So, as a next step you'll need to tell Prisma 2.0 what kind of database you use (MySQL or PostgreSQL) and where it is located.

First, you need to ensure that that provider field on the datasource block inside schema.prisma is configured to use the right database.

If you're using PostgreSQL, it needs to define the value postgresql in the provider field. If you're using MySQL, it needs to define the value mysql in the provider field. Switch around with the tabs in the code block to see examples of both:

PostgreSQL
MySQL
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

With the provider field properly set, you can go ahead and configure the connection URL inside the .env file.

Assume the database configuration in your Docker Compose file that you used to deploy your Prisma server looks as follows:

databases:
default:
connector: postgres
host: host.docker.internal
database: mydb
schema: public
user: janedoe
password: janedoe
ssl: false
rawAccess: true
port: '5432'
migrations: true

Based on these connection details, you need to configure the DATABASE_URL environment variable inside your .env file as follows:

DATABASE_URL="postgresql://janedoe:randompassword@localhost:5432/mydb?schema=public"

Note for PostgreSQL users: The schema argument is typically composed of your service name and service stage which are configured as the last two path componens on the endpoint in your prisma.yml.

For example, if your endpoint is http://localhost:4466/myproject/dev, the schema will be called myproject$dev. If the endpoint is http://localhost:4466/, the schema will be called default$default.

Learn more on the Connection URLs page.

2.3. Run the database introspection

For the purpose of this guide, we'll use an extended version of the data model from the REST API example to illustrate several things that are relevant during the upgrade process:

type User {
id: ID! @id
email: String! @unique
name: String
posts: [Post!]!
profile: Profile
}
type Post {
id: ID! @id
createdAt: DateTime! @createdAt
updatedAt: DateTime! @updatedAt
published: Boolean! @default(value: false)
title: String!
content: String
author: User!
categories: [Category!]!
}
type Profile {
id: ID! @id
bio: String
user: User! @relation(link: INLINE)
}
type Category {
id: ID! @id
name: String!
posts: [Post!]!
}

The above Prisma 1 datamodel is translated into the following SQL schema (in PostgreSQL dialect) when running prisma1 deploy:

CREATE TABLE test$dev."User" (
id character varying(25) PRIMARY KEY,
email text NOT NULL,
name text
);
CREATE UNIQUE INDEX "User_pkey" ON test$dev."User"(id text_ops);
CREATE UNIQUE INDEX "test$dev.User.email._UNIQUE" ON test$dev."User"(email text_ops);
CREATE TABLE test$dev."Post" (
id character varying(25) PRIMARY KEY,
"createdAt" timestamp(3) without time zone NOT NULL,
"updatedAt" timestamp(3) without time zone NOT NULL,
published boolean NOT NULL,
title text NOT NULL,
content text,
author character varying(25) REFERENCES test$dev."User"(id) ON DELETE SET NULL
);
CREATE UNIQUE INDEX "Post_pkey" ON test$dev."Post"(id text_ops);
CREATE TABLE test$dev."Profile" (
id character varying(25) PRIMARY KEY,
bio text,
user character varying(25) REFERENCES test$dev."User"(id) ON DELETE SET NULL
);
CREATE UNIQUE INDEX "Profile_pkey" ON test$dev."Profile"(id text_ops);
CREATE TABLE test$dev."Category" (
id character varying(25) PRIMARY KEY,
name text NOT NULL
);
CREATE UNIQUE INDEX "Category_pkey" ON test$dev."Category"(id text_ops);
CREATE TABLE test$dev."_CategoryToPost" (
"A" character varying(25) NOT NULL REFERENCES test$dev."Category"(id) ON DELETE CASCADE,
"B" character varying(25) NOT NULL REFERENCES test$dev."Post"(id) ON DELETE CASCADE
);
CREATE UNIQUE INDEX "_CategoryToPost_AB_unique" ON test$dev."_CategoryToPost"("A" text_ops,"B" text_ops);
CREATE INDEX "_CategoryToPost_B" ON test$dev."_CategoryToPost"("B" text_ops);

Note that this data model has three relations:

  • 1-1: UserProfile
  • 1-n: UserPost
  • m-n: PostCategory

Now you can run Prisma's introspection against your database with the following command:

npx prisma introspect

Here's a graphical illustration for what happens when introspect is invoked:

For the above Prisma 1 datamodel, this results in the following Prisma 2.0 schema (note that the models and fields have been reorded to match the initial order of the Prisma 1 datamodel):

model User {
id String @id
email String @unique
name String?
Post Post[]
Profile Profile[]
}
model Post {
id String @id
createdAt DateTime
updatedAt DateTime
published Boolean
title String
content String?
author String?
User User? @relation(fields: [author], references: [id])
Category Category[] @relation(references: [id])
}
model Profile {
id String @id
bio String?
user String?
User User? @relation(fields: [user], references: [id])
}
model Category {
id String @id
name String
Post Post[] @relation(references: [id])
}

As you might notice, the Prisma schema is missing or has adjusted some information from the Prisma 1 datamodel:

  • On the User model:
    • The previous posts relation field has been renamed to Post
    • The previous profile relation field has been renamed to Profile
    • The previous 1-1 relation between User and Profile has been turned into a 1-n relation
  • On the Post model:
    • The createdAt field doesn't have an attribute (previously called "directive" in Prisma 1)
    • The updatedAt field doesn't have an attribute (previously called "directive" in Prisma 1)
    • The published field misses a @default attribute
    • The relation to User is now represented with two fields:
      • The type of author is now String and not User
      • The relation field User is now optional and uses the @relation attribute
    • The previous categories relation field has been renamed to Category and uses the @relation attribute
  • On the Profile model:
    • The relation to User is now represented with two fields:
      • The type of user is now String and not User
      • The relation field User is now optional and uses the @relation attribute
  • On the Category model:
    • The previous posts relation field has been renamed to Post and uses the @relation attribute

Also note that that with Prisma 2.0, you alway must explicitly specify @default attributes if you want Prisma to generate IDs for you by default. Since none of the @id fields have @default values at the moment, you would need to supply your own ID values when creating new records with the new Prisma Client!

2.4. Fixing the Prisma 2.0 schema

As pointed out above, the Prisma 2.0 schema that was generated from introspection has changed and even misses a lot of information from the previous Prisma 1 datamodel.

The main reason for this is that in Prisma 1, most of these features have been implemented by Prisma and did not actually manifest in the database. For example, @default directives in Prisma 1 were not mapped to DEFAULT constraints in SQL – instead the Prisma server would take care of generating these default values and inserting them into the database at runtime (if you took a look at the SQL schema that was shown in the expandable element above, you probably also noticed that).

Because much of the information from the Prisma 1 datamodel does not manifest in the database schema, it can't be recognized by Prisma's introspection (which is the reason why it doesn't appear in the new Prisma schema).

Note: One major goal of Prisma 2.0 is to provide a cleaner mapping from the Prisma schema to the database. With Prisma 2.0, most of the features from the Prisma schema do manifest in the database, with a few exceptions.

You generally have two ways to resolve many of the resulting issues:

  • Manually adjust your database schema using SQL and re-introspect
  • Adjust your Prisma schema to manually add the missing information

Note: We are currently working on dedicated tooling that will help you to perform these tasks automatically. Please subscribe to this Github issue to get updates about the progress of these upgrade tools.

Note that adjusting your database schema using SQL can not resolve all issues, you will need to make manual adjustments to your Prisma schema as well during the upgrade process!

For this guide, we'll take the path of manually adjusting the Prisma schema and not touching the database at all.

Note: Any manual changes you make to your Prisma schema will be lost after you re-run introspection because the Prisma schema file will be overwritten. It is therefore highly recommended to backup your Prisma schema before you're re-running introspection.

Adjusting the User model

The User model that was generated from introspection looks as follows (fields have been reordered to match the field order from the Prisma 1 datamodel):

model User {
id String @id
email String @unique
name String?
Post Post[]
Profile Profile[]
}

Recall the issues that need to be fixed here:

  • The previous posts relation field has been renamed to Post
  • The previous profile relation field has been renamed to Profile
  • The previous 1-1 relation between User and Profile has been turned into a 1-n relation
  • The @id field doesn't have a default value

The first one is fairly straightforward to resolve. Relation fields do not manifest in the underlying database and therefore are only relevant for the generated Prisma Client API. When generated from introspection, relation fields are named after the model they relate to (in this case the relation field is called Post because it denotes a relation to the Post model).

You can name these anything you like, so it can be renamed to posts again to match the name of the Prisma 1 datamodel.:

model User {
id String @id
email String @unique
name String?
+ posts Post[]
Profile Profile[]
}

The same for Profile, it can be lowercased to profile to match the name of the Prisma 1 data model.

Introspection also turned the prior 1-1 relation into an 1-n relation. That's because the foreign key column user on the Profile table does not have a UNIQUE constraint in the database. Prisma therefore interprets it as a 1-n relation because there might be multiple Profile records pointing to the same User record (in Prisma 1, 1-1 relations were implemented on a Prisma-level and therefore the UNIQUE constraint is missing).

To fix this, you can remove the [] after the Profile type:

model User {
id String @id
email String @unique
name String?
posts Post[]
+ profile Profile
}

Finally, you need to ensure that the id field is populated with default values. Prisma 1 used cuid values implicitly. In Prisma 2.0, you need to specify this via the @default attribute:

model User {
+ id String @id @default(cuid())
email String @unique
name String?
posts Post[]
profile Profile
}

This is the final User type after all adjustments:

model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
profile Profile
}

Adjusting the Post model

The Post model that was generated from introspection looks as follows (fields have been reordered to match the field order from the Prisma 1 datamodel):

model Post {
id String @id
createdAt DateTime
updatedAt DateTime
published Boolean
title String
content String?
author String?
User User? @relation(fields: [author], references: [id])
Category Category[] @relation(references: [id])
}

Recall the issues that need to be fixed here:

  • The createdAt field doesn't have an attribute (previously called "directive" in Prisma 1)
  • The updatedAt field doesn't have an attribute (previously called "directive" in Prisma 1)
  • The published field misses a @default attribute
  • The relation to User is now represented with two fields:
    • The type of author is now String and not User
    • The relation field User is now optional and uses the @relation attribute
  • The previous categories relation field has been renamed to Category and uses the @relation attribute
  • The @id field doesn't have a default value

The @createdAt attribute from Prisma 1 is represented via the @default(now()) attribute in Prisma 2.0. @updatedAt still exists in the same way as before:

model Post {
id String @id
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
published Boolean
title String
content String?
author String?
User User? @relation(fields: [author], references: [id])
Category Category[] @relation(references: [id])
}

Similarly you can add the @default attribute to published like so:

model Post {
id String @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
+ published Boolean @default(false)
title String
content String?
author String?
User User? @relation(fields: [author], references: [id])
Category Category[] @relation(references: [id])
}

Note: In Prisma 2.0, the @default attribute works on both the Prisma-level and the database-level. So, while there's not DEFAULT constraint defined in the database, you can still add it to your Prisma schema and Prisma Client will insert the default values for you. Note that if the database specifies a different default value than Prisma Client, the default value from Prisma Client takes precedence.

Moving on to the author relation field from Prisma 1 that has been split into two fields during introspection. The reason why this happened is because the first Prisma 2.0 Beta introduced a new relation syntax which requires a relation field with a relation scalar on one side of a relation.

The recommended way to resolve this is by renaming the relation scalar field and mapping it to the foreign key in the underlying database using @map. That way you can reuse the same name for the relation that you used in the Prisma 1 datamodel:

model Post {
id String @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
published Boolean @default(false)
title String
content String?
+ authorId String? @map("author")
+ author User? @relation(fields: [authorId], references: [id])
Category Category[] @relation(references: [id])
}

Finally, you can also rename the Category field to categories:

model Post {
id  String @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
published  Boolean @default(false)
title  String
content  String?
authorId String? @map("author")
author User? @relation(fields: [authorId], references: [id])
+ categories Category[] @relation(references: [id])
}

This is the Post model after all adjustments:

model Post {
id  String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
published  Boolean @default(false)
title  String
content  String?
authorId String? @map("author")
author User? @relation(fields: [authorId], references: [id])
categories Category[] @relation(references: [id])
}

Adjusting the Profile model

The Profile model that was generated from introspection looks as follows (fields have been reordered to match the field order from the Prisma 1 datamodel):

model Profile {
id String @id
bio String?
user String?
User User? @relation(fields: [user], references: [id])
}

Recall the issues that need to be fixed here:

  • The relation to User is now represented with two fields:
    • The type of user is now String and not User
    • The relation field User is now optional and uses the @relation attribute
  • The @id field doesn't have a default value

Similar to how the issue with the two relation fields was resolved on Post (by using @map) you can also resolve it here:

model Profile {
id String @id
bio String?
+ userId String?
+ user User? @relation(fields: [userId], references: [id])
}

This is the Profile model after all adjustments:

model Profile {
id String @id @default(cuid())
bio String?
userId String?
user User? @relation(fields: [userId], references: [id])
}

Adjusting the Category model

The Category model that was generated from introspection looks as follows (fields have been reordered to match the field order from the Prisma 1 datamodel):

model Category {
id String @id
name String
Post Post[] @relation(references: [id])
}

Recall the issue that needs to be fixed here:

  • The previous posts relation field has been renamed to Post and uses the @relation attribute
  • The @id field doesn't have a default value

Because the Post relation field does not manifest in the database schema, you can name it whatever you like in the Prisma schema without an extra mapping. So you can rename it to posts again:

model Category {
id String @id
name String
+ posts Post[] @relation(references: [id])
}

This is the Category model after all adjustments:

model Category {
id String @id @default(cuid())
name String
posts Post[] @relation(references: [id])
}

Other issues that are not mentioned in this guide

Additionally to the issues that were explained in the previous sections, you might encounter other friction points:

  • Cascading deletes in Prisma 1 were implemented by Prisma and did not manifest in the database. The only way to get similar behavior with Prisma 2.0 at the moment is by configuring it on the database-level. You can follow the guides for PostgreSQL and MySQL for this.
  • The JSON type from Prisma 1 currently gets mapped to String in Prisma 2. The only way to resolve this is by adjusting the column type in the database to JSON.
  • Enums in Prisma 1 used to be represented as strings in the underlying database. We'll provide more info on how you can upgrade these soon.
  • Scalar lists (arrays) in Prisma 1 used to be implemented using an extra table in the underlying database. We'll provide more info on how you can upgrade these soon.

3. Adjust the application to use Prisma Client 2.0

With all of the adjustments to the Prisma schema in place, you can now generate Prisma Client 2.0 and adjust your application code!

Prisma Client 2.0 is generated into node_modules/@prisma/client. In order for this package to "survive" the pruning of Node.js package managers, you first need to install it as an npm dependency:

npm install @prisma/client

The next thing you need to do in order to be able use Prisma Client 2.0 in your application code is to generate it. Similar to Prisma 1, the generators in your Prisma schema file can be invoked by running the generate CLI command:

npx prisma generate

To make the migration complete, you have to change your application code and replace the usage of the Prisma client with the new Prisma Client 2.0.

The application code in our example is located in a single file and looks as follows:

import * as express from 'express'
import * as bodyParser from 'body-parser'
import { prisma } from './generated/prisma-client'
const app = express()
app.use(bodyParser.json())
app.post(`/user`, async (req, res) => {
const result = await prisma.createUser({
...req.body,
})
res.json(result)
})
app.post(`/post`, async (req, res) => {
const { title, content, authorEmail } = req.body
const result = await prisma.createPost({
title: title,
content: content,
author: { connect: { email: authorEmail } },
})
res.json(result)
})
app.put('/publish/:id', async (req, res) => {
const { id } = req.params
const post = await prisma.updatePost({
where: { id },
data: { published: true },
})
res.json(post)
})
app.delete(`/post/:id`, async (req, res) => {
const { id } = req.params
const post = await prisma.deletePost({ id })
res.json(post)
})
app.get(`/post/:id`, async (req, res) => {
const { id } = req.params
const post = await prisma.post({ id })
res.json(post)
})
app.get('/feed', async (req, res) => {
const posts = await prisma.post({ where: { published: true } })
res.json(posts)
})
app.get('/filterPosts', async (req, res) => {
const { searchString } = req.query
const draftPosts = await prisma.post({
where: {
OR: [
{
title_contains: searchString,
},
{
content_contains: searchString,
},
],
},
})
res.json(draftPosts)
})
app.listen(3000, () =>
console.log('Server is running on http://localhost:3000'),
)

Consider each occurence of the Prisma client instance prisma and replacing with the respective usage of Prisma Client 2.0. You can learn more in the API Reference.

3.1. Adjusting the import

Since Prisma Client 2.0 is generated into node_modules/@prisma/client, it is imported as follows:

import { PrismaClient } from '@prisma/client'

Note that this only imports the PrismaClient constructor, so you also need to instantiate a Prisma Client 2.0 instance:

const prisma = new PrismaClient()

3.2. Adjusting the /user route (POST)

With the Prisma Client 2.0 API, the /user route for POST requests has to be changed to:

app.post(`/user`, async (req, res) => {
const result = await prisma.user.create({
data: {
...req.body,
},
})
res.json(result)
})

3.3. Adjusting the /post route (POST)

With the Prisma Client 2.0 API, the /post route for POST requests has to be changed to:

app.post(`/post`, async (req, res) => {
const { title, content, authorEmail } = req.body
const result = await prisma.post.create({
data: {
title: title,
content: content,
author: { connect: { email: authorEmail } },
},
})
res.json(result)
})

3.4. Adjusting the /publish/:id route (PUT)

With the Prisma Client 2.0 API, the /publish/:id route for PUT requests has to be changed to:

app.put('/publish/:id', async (req, res) => {
const { id } = req.params
const post = await prisma.post.update({
where: { id },
data: { published: true },
})
res.json(post)
})

3.5. Adjusting the /post/:id route (DELETE)

With the Prisma Client 2.0 API, the //post/:id route for DELETE requests has to be changed to:

app.delete(`/post/:id`, async (req, res) => {
const { id } = req.params
const post = await prisma.post.delete({
where: { id }
})
res.json(post)
})

3.6. Adjusting the /post/:id route (GET)

With the Prisma Client 2.0 API, the /post/:id route for GET requests has to be changed to:

app.get(`/post/:id`, async (req, res) => {
const { id } = req.params
const post = await prisma.post.findOne({
where: { id }
})
res.json(post)
})

3.7. Adjusting the /feed route (GET)

With the Prisma Client 2.0 API, the /feed route for GET requests has to be changed to:

app.get('/feed', async (req, res) => {
const posts = await prisma.post.findMany({ where: { published: true } })
res.json(posts)
})

3.8. Adjusting the /filterPosts route (GET)

With the Prisma Client 2.0 API, the /user route for POST requests has to be changed to:

app.get('/filterPosts', async (req, res) => {
const { searchString } = req.query
const filteredPosts = await prisma.post.findMany({
where: {
OR: [
{
title: { contains: searchString }
},
{
content: { contains: searchString }
},
],
},
})
res.json(filteredPosts)
})

4. Performing database migrations with Prisma Migrate

Going forward, you won't perform schema migrations using the prisma deploy command any more. Instead, you can use the prisma migrate commands. Every schema migration follows a 3-step-process:

  1. Adjust the data model inside your Prisma schema to reflect the desired change (e.g. adding a new model)
  2. Run npx prisma migrate save --experimental to save the migration on your file system (this doesn't perform the migration yet)
  3. Run npx prisma migrate up --experimental to actually perform the migration against your database

Warning: Prisma Migrate is currently in an experimental state. When using any of the commands below, you need to explicitly opt-in via an --experimental flag, e.g. prisma migrate save --name 'init' --experimental.

Summary

In this upgrade guide, you learned how to upgrade an Express-based REST API from Prisma 1 to Prisma 2.0 that uses Prisma Client 2.0 and Prisma Migrate. In the future, we'll cover more fine-grained upgrade scenarios, based on more complicated database schemas as well as for projects that are using GraphQL Nexus and nexus-prisma.

Be sure to subscribe to this GitHub issue to receive updates on the state of upgrade guides!

Edit this page on Github