Skip to main content
Prisma Documentation Docs

Search documentation

Type to search this documentation.

On this pageOverview

Customizing migrations

In some scenarios, you need to edit a migration file before you apply it. For example, to change the direction of a 1-1 relation (moving the foreign key from one side to another) without data loss, you need to move data as part of the migration - this SQL is not part of the default migration, and must be written by hand.

This guide explains how to edit migration files and gives some examples of use cases where you may want to do this.

To edit a migration file before applying it, the general procedure is the following:

  1. Make a schema change that requires custom SQL (for example, to preserve existing data)

  2. Create a draft migration using:

    bunx prisma migrate dev --create-only
    Bash
    pnpm prisma migrate dev --create-only
    Bash
    yarn prisma migrate dev --create-only
    Bash
    npx prisma migrate dev --create-only
    1. Modify the generated SQL file.
    2. Apply the modified SQL by running:
  3. Modify the generated SQL file.

  4. Apply the modified SQL by running:

    title="bun"
    bunx prisma migrate dev
    pnpm
    pnpm prisma migrate dev
    yarn
    yarn prisma migrate dev
    npm
    npx prisma migrate dev

By default, renaming a field in the schema results in a migration that will:

  • CREATE a new column (for example, fullname)
  • DROP the existing column (for example, name) and the data in that column

To actually rename a field and avoid data loss when you run the migration in production, you need to modify the generated migration SQL before applying it to the database. Consider the following schema fragment - the biograpy field is spelled wrong.

model Profile {

  id       Int    @id @default(autoincrement())

  biograpy String

  userId   Int    @unique

  user     User   @relation(fields: [userId], references: [id])

}

To rename the biograpy field to biography:

  1. Rename the field in the schema:

    model Profile {
    
      id        Int    @id @default(autoincrement())
    
      biograpy  String
    
      biography String
    
      userId    Int    @unique
    
      user      User   @relation(fields: [userId], references: [id])
    
    }
  2. Run the following command to create a draft migration that you can edit before applying to the database:

    bunx prisma migrate dev --name rename-migration --create-only
    Bash
    pnpm prisma migrate dev --name rename-migration --create-only
    Bash
    yarn prisma migrate dev --name rename-migration --create-only
    Bash
    npx prisma migrate dev --name rename-migration --create-only
    1. Edit the draft migration as shown, changing DROP / DELETE to a single RENAME COLUMN:
  3. Edit the draft migration as shown, changing DROP / DELETE to a single RENAME COLUMN:

    title="Before"
    ALTER TABLE "Profile" DROP COLUMN "biograpy",
    
    ADD COLUMN  "biography" TEXT NOT NULL;
    After
    ALTER TABLE "Profile"
    RENAME COLUMN "biograpy" TO "biography"

    For SQL Server, you should use the stored procedure sp_rename instead of ALTER TABLE RENAME COLUMN.

    title="After"
     EXEC sp_rename 'dbo.Profile.biograpy', 'biography', 'COLUMN';
  4. Save and apply the migration:

    bunx prisma migrate dev
    Bash
    pnpm prisma migrate dev
    Bash
    yarn prisma migrate dev
    Bash
    npx prisma migrate dev

    You can use the same technique to rename a model - edit the generated SQL to rename the table rather than drop and re-create it.

You can use the same technique to rename a model - edit the generated SQL to rename the table rather than drop and re-create it.

Making schema changes to existing fields, e.g., renaming a field can lead to downtime. It happens in the time frame between applying a migration that modifies an existing field, and deploying a new version of the application code which uses the modified field.

You can prevent downtime by breaking down the steps required to alter a field into a series of discrete steps designed to introduce the change gradually. This pattern is known as the expand and contract pattern.

The pattern involves two components: your application code accessing the database and the database schema you intend to alter.

With the expand and contract pattern, renaming the field bio to biography would look as follows with Prisma:

  1. Add the new biography field to your Prisma schema and create a migration

    model Profile {
    
      id        Int    @id @default(autoincrement())
    
      bio       String
    
      biography String
    
      userId    Int    @unique
    
      user      User   @relation(fields: [userId], references: [id])
    
    }
  2. Expand: update the application code and write to both the bio and biography fields, but continue reading from the bio field, and deploy the code

  3. Create an empty migration and copy existing data from the bio to the biography field

    bunx prisma migrate dev --name copy_biography --create-only
    Bash
    pnpm prisma migrate dev --name copy_biography --create-only
    Bash
    yarn prisma migrate dev --name copy_biography --create-only
    Bash
    npx prisma migrate dev --name copy_biography --create-only
    prisma/migrations/20210420000000_copy_biography/migration.sql
    UPDATE "Profile" SET biography = bio;
    1. Verify the integrity of the biography field in the database
    2. Update application code to read from the new biography field
    3. Update application code to stop writing to the bio field
    4. Contract: remove the bio from the Prisma schema, and create a migration to remove the bio field
      prisma
      model Profile {  id        Int    @id @default(autoincrement())  bio       String  biography String  userId    Int    @unique  user      User   @relation(fields: [userId], references: [id])}
    title="prisma/migrations/20210420000000_copy_biography/migration.sql"
    UPDATE "Profile" SET biography = bio;
  4. Verify the integrity of the biography field in the database

  5. Update application code to read from the new biography field

  6. Update application code to stop writing to the bio field

  7. Contract: remove the bio from the Prisma schema, and create a migration to remove the bio field

    model Profile {
    
      id        Int    @id @default(autoincrement())
    
      bio       String
    
      biography String
    
      userId    Int    @unique
    
      user      User   @relation(fields: [userId], references: [id])
    
    }
    bunx prisma migrate dev --name remove_bio
    Bash
    pnpm prisma migrate dev --name remove_bio
    Bash
    yarn prisma migrate dev --name remove_bio
    Bash
    npx prisma migrate dev --name remove_bio

    By using this approach, you avoid potential downtime that altering existing fields that are used in the application code are prone to, and reduce the amount of coordination required between applying the migration and deploying the updated application code.

    Note that this pattern is applicable in any situation involving a change to a column that has data and is in use by the application code. Examples include combining two fields into one, or transforming a 1:n relation to a m:n relation.

    To learn more, check out the Data Guide article on the expand and contract pattern

By using this approach, you avoid potential downtime that altering existing fields that are used in the application code are prone to, and reduce the amount of coordination required between applying the migration and deploying the updated application code.

Note that this pattern is applicable in any situation involving a change to a column that has data and is in use by the application code. Examples include combining two fields into one, or transforming a 1:n relation to a m:n relation.

To learn more, check out the Data Guide article on the expand and contract pattern

To change the direction of a 1-1 relation:

  1. Make the change in the schema:

    model User {
    
      id        Int      @id @default(autoincrement())
    
      name      String
    
      posts     Post[]
    
      profile   Profile? @relation(fields: [profileId], references: [id])
    
      profileId Int      @unique
    
    }
    
    model Profile {
    
      id        Int    @id @default(autoincrement())
    
      biography String
    
      user      User
    
    }
  2. Run the following command to create a draft migration that you can edit before applying to the database:

    bunx prisma migrate dev --name rename-migration --create-only
    Bash
    pnpm prisma migrate dev --name rename-migration --create-only
    Bash
    yarn prisma migrate dev --name rename-migration --create-only
    Bash
    npx prisma migrate dev --name rename-migration --create-only
    no-copy
    ⚠️  There will be data loss when applying the migration:
    
    • The migration will add a unique constraint covering the columns `[profileId]` on the table `User`. If there are existing duplicate values, the migration will fail.
    1. Edit the draft migration as shown:
    ⚠️  There will be data loss when applying the migration:
    
    • The migration will add a unique constraint covering the columns `[profileId]` on the table `User`. If there are existing duplicate values, the migration will fail.
  3. Edit the draft migration as shown:

    
    -- DropForeignKey
    
    ALTER TABLE "Profile" DROP CONSTRAINT "Profile_userId_fkey";
    
    -- DropIndex
    
    DROP INDEX "Profile_userId_unique";
    
    -- AlterTable
    
    ALTER TABLE "Profile" DROP COLUMN "userId";
    
    -- AlterTable
    
    ALTER TABLE "User" ADD COLUMN     "profileId" INTEGER NOT NULL;
    
    -- CreateIndex
    
    CREATE UNIQUE INDEX "User_profileId_unique" ON "User"("profileId");
    
    -- AddForeignKey
    
    ALTER TABLE "User" ADD FOREIGN KEY ("profileId") REFERENCES "Profile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
    ./prisma/migrations/20210308092620_rename_migration/migration.sql
     EXEC sp_rename 'dbo.Profile.biograpy', 'biography', 'COLUMN';
    1. Save and apply the migration:
  4. Save and apply the migration:

    title="bun"
    bunx prisma migrate dev
    pnpm
    pnpm prisma migrate dev
    yarn
    yarn prisma migrate dev
    npm
    npx prisma migrate dev
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu