Migrations (PostgreSQL)
Overview
You can configure Prisma with your PostgreSQL database in either of two ways:
- Enable database migrations through Prisma: This means all changes to your database schema must be made through Prisma (by adjusting your datamodel and using the
prisma deploycommand). You can achieve this by setting themigrationsflag in thePRISMA_CONFIGvariable of your Prisma server totrue. - Disable database migrations through Prisma: This means none of the changes to your database schema can be made by Prisma, all migrations must be performed manually and directly against the database. You can achieve this by setting the
migrationsflag in thePRISMA_CONFIGvariable of your Prisma server tofalse.
Note that the
migrationsflag will be removed at some point and Prisma's migration model will become more flexible. This means you can either use the Prisma CLI to perform migrations withprisma deployor perform your migrations manually. Learn more in this GitHub issue or explore the spec for the upcoming Prisma version.
Enabling database migrations
To enable database migrations, set the migrations property to true:
PRISMA_CONFIG: |
managementApiSecret: __YOUR_MANAGEMENT_API_SECRET__
port: 4466
databases:
default:
connector: postgres
migrations: true
host: __YOUR_DATABASE_HOST__
port: __YOUR_DATABASE_PORT__
user: __YOUR_DATABASE_USER__
password: __YOUR_DATABASE_PASSWORD__
connectionLimit: __YOUR_CONNECTION_LIMIT__
If database migrations are enabled, you use SDL to define and migrate your database schema. There are two steps to every migration:
- Adjust the datamodel file to reflect the new desired schema
- Run
prisma deployto apply the changes and perform the migration of the underlying database
Migration operations
Prisma uses temporary directives to perform one-time migration operations. After deploying a service that contain a temporary directive, a temporary directive needs to be manually removed from the datamodel file.
Renaming
The temporary directive @rename(oldName: String!) is used to rename a type or a field of a type.
If the @rename directive is not used, Prisma deletes old type/field before creating the new one, resulting in loss of data!
Renaming a type
Here is an example scenario:
1) Before migration
type Post {
text: String
}
2) Goal
Rename the Post type to Story
3) Adding the @rename directive
# renaming the `Post` type to `Story`
type Story @rename(oldName: "Post") {
text: String
}
4) Migrating the database with prisma deploy
After having the saved the datamodel file with these changes, you need to run:
prisma deploy
5) Removing the @rename directive manually
type Story {
text: String
}
Renaming a field
Here is an example scenario:
1) Before migration
type Post {
text: String
}
2) Goal
Rename the text field to content
3) Adding the @rename directive
# renaming the `text` field to `content`
type Post {
content: String @rename(oldName: "text")
}
4) Migrating the database with prisma deploy
After having the saved the datamodel file with these changes, you need to run:
prisma deploy
5) Removing the @rename directive manually
type Post {
content: String
}
Limitations
- It is currently not possible to rename relations that are specified via the
@relationdirective.
Disabling database migrations
To disable database migrations, set the migrations property to false:
PRISMA_CONFIG: |
managementApiSecret: __YOUR_MANAGEMENT_API_SECRET__
port: 4466
databases:
default:
connector: postgres
migrations: false
host: __YOUR_DATABASE_HOST__
port: __YOUR_DATABASE_PORT__
user: __YOUR_DATABASE_USER__
password: __YOUR_DATABASE_PASSWORD__
connectionLimit: __YOUR_CONNECTION_LIMIT__
When migrations are disabled, you need to manually ensure that your datamodel is in sync with the unterlying database schema, otherwise the Prisma API might exhibit undefined behaviour!
This means you need to ensure that:
- Every type in your datamodel is mapped to a database table using the
@pgTabledirective - Every field on any type of your datamodel is also present as a column on the corresponding database table
- Every relation in your datamodel needs to be annotated with the
@pgRelationdirective
Note that you can exlude tables and/or fields from your database in the datamodel. For example, if you have a user table with a password column, you don't need to include the password field in your datamodel, or you can leave out the user type altogether. In that case, the structues that are not defined in the datamodel will not be exposed by Prisma.
You can use the prisma introspect command to generate a datamodel based on your current database schema. Learn more about database introspection with PostgreSQL here.
The prisma introspect command introspects your database schema and creates a datamodel file based on that. The name of the datamodel file will include a timestamp so that the generated datamodel doesn't conflict with your existing one, e.g. datamodel-1547547645423.prisma.
prisma introspect does not change your database schema. It only generates the temporary datamodel file that reflects the current database schema. You can use this temporary file as a helper to adjust your actual datamodel by copying and pasting the new types and fields into it. Once you're happy with the adjusted datamodel, you need to run prisma deploy to actually apply the changes and update the Prisma API.