Skip to content
Back to the blog

Prisma in production: review migrations before changing a database with data

Distinguish empty and existing databases, review SQL, and check data, constraints and permissions before applying Prisma migrations.

  • Prisma
  • PostgreSQL
  • AI

An AI-built application can work with a local database and fail when published. Creating tables on another server, moving records and changing the schema of a database that already contains data are three different operations. A Prisma migration does not automatically copy rows from your computer to production.

This guide is prepared for Prisma 7.10.0, pinned in the project. Current documentation also describes Prisma 8 commands: check the installed version before copying a recipe. The local experiment described below has completed; it does not demonstrate native Hostbrid integration.

First identify the database you are changing

If the destination is empty and you have a reviewed migration history, you can apply that history to the destination. If tables or data already exist, review how the schema was created and whether Prisma has a history that matches it. P3005, “database schema is not empty”, is not solved by deleting a database you need to retain.

An existing database may require a baseline: an initial migration representing its existing schema, recorded as applied after verifying that correspondence. Do not mark an arbitrary file as applied to hide an error. An incorrect marker leaves the history and actual schema in different states and can move the problem to the next release.

If you also want to move data from your computer, prepare a separate export and import operation, with compatible versions and a suitable destination. Check who will continue writing during the transfer. A screenshot of newly created tables does not prove that every row, relationship or sequence arrived.

Do not use the development command for production delivery

In Prisma 7, migrate dev generates and applies migrations during development; it can detect differences that require a reset. migrate reset deletes data. migrate deploy applies existing pending migrations: it does not generate a new migration or the client for you, and it does not check every schema difference.

This does not make migrate deploy a preservation guarantee. If the SQL file contains a DROP TABLE, a removed column or an incorrect transformation, applying it can destroy information. Review the SQL change, not just the command’s final message. Pinning the version and retaining the lockfile makes the experiment reproducible; it does not make every change correct.

Test the change with records that reveal data loss

Work on a disposable database you control. Include records with known identifiers, relationships and values that must survive. Compare those values before and after, not just the row count. Two tables can contain the same number of rows and different data.

A new required field needs a strategy for existing rows. You can introduce it as nullable, populate values through an explicit transformation, then enforce the constraint after checking that no nulls remain. Also check the unique constraints and foreign keys your application needs.

Apply the history again to the same destination to check what remains pending. That result does not replace SQL review, a recovery rehearsal or compatibility between your application’s previous and new versions. A backup you have never restored does not prove you can recover the service.

Decide where the migration can run

A DATABASE_URL contains private access details; do not put it in public variables such as VITE_, in the repository or in examples you share. The process running the migration must reach the database and have suitable permissions for the approved changes. The running application may need different permissions.

Hostbrid offers relational databases and describes a private network by default on its databases page. Check how your migration process will reach that network before purchasing or connecting an external CI service. This guide does not demonstrate access from every CI provider or automatic Prisma configuration. Consult current plans and confirm the engine and connectivity your application needs.

If you do not yet know which part of your project needs a server, start with choosing hosting for an AI-built website. Publishing the frontend and maintaining a production database are related decisions that require their own checks.

What we checked in the original example

On October 8 we tested 12 cases with Prisma 7.10.0, Node 22.23.3, npm 10.9.9 and PostgreSQL 16.13 Homebrew on macOS ARM64. The cluster was new and local, with two synthetic accounts and two entries. We connected to neither a Hostbrid database nor a customer’s database.

The additive migration retained every original field, ID and relationship; the backfill produced the expected names. Constraints rejected duplicates and invalid references. The existing-database branch reproduced P3005 before baselining; a correct baseline and an empty schema diff allowed the additive migration. With an incorrect baseline, resolve succeeded, but the diff detected missing constraints and the experiment did not proceed.

We restored the dump into three new databases and compared the data. In another copy, a DROP COLUMN succeeded and removed values: keeping the row count was insufficient. Adding a required column without filling existing rows failed; the next deploy was blocked. These negative results were expected and affected only synthetic data.

The server was stopped and its stopped state checked. This does not test large tables, concurrency, lock durations, PITR, provider backups or running migrations inside Projects.

Prisma 7 migrate deploy · Prisma 7 baselining

Run the experiment in a disposable environment

The original MIT example is pinned to revision 87a2a843867be8b6244a68fbc50b3919f4d2b82e. It requires macOS ARM64, Node 22.23.3, npm 10.9.9, installed PostgreSQL 16.13 Homebrew and a free local port 55439. PG_BIN selects the binaries directory. Do not adapt these counterexamples to run against a real database: the runner creates and stops its own cluster and ignores an incoming DATABASE_URL.

git clone https://github.com/ocentelles/hostbrid-example-prisma-migrations.git
cd hostbrid-example-prisma-migrations
git checkout --detach 87a2a843867be8b6244a68fbc50b3919f4d2b82e
node --version
npm --version
npm ci --ignore-scripts --no-audit --no-fund
npm run essay

Manage your sites, servers and email.

Forgot your password?

Free, and it takes a minute.

At least 8 characters. Not all digits, not a common one.

We'll email you to confirm the account.