Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
LiçãoIntermediáriocódigo testado

Migrations no Prisma 7: dev, status e deploy

Crie, revise e aplique migrations do Prisma 7 no PostgreSQL, trate uma coluna obrigatória com dados existentes e separe migrate dev de migrate deploy.

Rodolfo Mori6 min de leitura

Migration no Prisma é um arquivo SQL versionado que leva o banco de uma estrutura conhecida para a próxima. prisma migrate dev cria e aplica mudanças no ambiente de desenvolvimento; prisma migrate status compara histórico e banco; prisma migrate deploy aplica migrations pendentes em staging ou produção.

Nesta lição, você criará uma tabela, inserirá dados e tentará adicionar uma coluna obrigatória. O Prisma recusará a mudança porque duas linhas já existem. Depois a gente fará uma evolução em etapas, revisará o SQL e aplicará o mesmo histórico num banco limpo.

O ponto de partida é ter concluído a instalação do Prisma 7 com PostgreSQL e saber como models e atributos formam o schema. Se NOT NULL, índice e foreign key ainda não estão claros, consulte também o guia de PostgreSQL enquanto lê o SQL gerado.

Reforma com caderno de obras: o modelo mental

Imagine uma loja que abre todos os dias. A planta desejada mostra uma nova sala, mas a equipe precisa de um caderno de obras: qual parede será alterada, em que ordem e o que acontece com o estoque que já ocupa o espaço. Entregar só a planta final não explica como sair do estado atual sem perda.

No mapa técnico, schema.prisma é o estado desejado, cada migration.sql é uma etapa da obra, a tabela _prisma_migrations é o registro do que já foi aplicado e PostgreSQL é a loja em funcionamento. O limite da analogia: migrations podem incluir transformação de dados e operações que bloqueiam concorrência; revisar o SQL e planejar rollout continua necessário.

O comportamento essencial é sequencial. Cada ambiente aplica o mesmo histórico na mesma ordem. Editar uma migration antiga depois que outra máquina a executou é como trocar uma página do caderno sem mudar a obra que já aconteceu.

A configuração aponta schema, pasta e conexão

No Prisma 7, a CLI lê as rotas e a URL em prisma.config.ts:

ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});

Use uma base de desenvolvimento que possa ser recriada. migrate dev precisa de shadow database para reexecutar o histórico e detectar drift. Credenciais com permissão limitada demais podem impedir essa etapa; não resolva apontando o comando para produção.

A primeira migration cria um ponto de partida

Comece com Livro:

text
generator client {
  provider     = "prisma-client"
  output       = "../generated/prisma"
  moduleFormat = "esm"
}

datasource db {
  provider = "postgresql"
}

model Livro {
  id     Int    @id @default(autoincrement())
  titulo String

  @@map("livros")
}

Crie e aplique a migration em desenvolvimento:

bash
npx prisma migrate dev --name inicial
Applying migration `20260823013543_inicial`

The following migration(s) have been created and applied from new schema changes:

prisma/migrations/ └─ 20260823013543_inicial/ └─ migration.sql

Your database is now in sync with your schema.

Seu timestamp será diferente. O nome inicial ajuda pessoas a reconhecer a intenção; não precisa descrever cada coluna. A pasta e o SQL entram no Git junto da alteração do schema.

Leia o SQL antes de aceitar a mudança

O arquivo produzido no teste contém:

sql
CREATE TABLE "livros" (
    "id" SERIAL NOT NULL,
    "titulo" TEXT NOT NULL,

    CONSTRAINT "livros_pkey" PRIMARY KEY ("id")
);

Confira NOT NULL, defaults, índices e foreign keys. Em alterações grandes, procure operações que reescrevem tabela, adquirem lock forte ou falham diante de dados existentes. Prisma gera o ponto de partida, mas você é responsável por aprovar o SQL.

O histórico agora tem duas representações no banco: a tabela livros e a linha registrada em _prisma_migrations. Veja o estado:

bash
npx prisma migrate status
1 migration found in prisma/migrations

Database schema is up to date!

“Up to date” significa que o histórico local e as migrations registradas como aplicadas concordam. O comando não compara cada tabela com schema.prisma, não prova que os dados estão corretos e não substitui a detecção de drift feita por migrate dev no ambiente de desenvolvimento.

Uma coluna obrigatória encontra dados antigos

Depois da primeira migration, o teste inseriu dois livros:

sql
INSERT INTO livros (titulo)
VALUES ('Olhos d''água'), ('Becos da memória');

Agora acrescente ISBN obrigatório:

text
model Livro {
  id     Int    @id @default(autoincrement())
  titulo String
  isbn   String @unique

  @@map("livros")
}

Ao rodar npx prisma migrate dev --name isbn_obrigatorio, a saída real foi:

Error: ⚠️ We found changes that cannot be executed:

• Step 0 Added the required column isbn to the livros table without a default value. There are 2 rows in this table, it is not possible to execute this step.

You can use prisma migrate dev –create-only to create the migration file, and manually modify it to address the underlying issue(s).

O erro protege dados que já existem. PostgreSQL não sabe qual ISBN preencher nas duas linhas, e NOT NULL proíbe ausência. Inventar um default igual para todas também violaria unique e seria uma regra falsa.

Evolua em etapas quando a tabela já tem linhas

Uma estratégia segura é adicionar a coluna opcional, publicar código que preenche os registros antigos e só depois torná-la obrigatória. Primeiro:

text
model Livro {
  id     Int     @id @default(autoincrement())
  titulo String
  isbn   String? @unique

  @@map("livros")
}

Crie adiciona_isbn, leia o aviso de unicidade e confirme no ambiente de desenvolvimento. O SQL testado foi:

sql
ALTER TABLE "livros" ADD COLUMN "isbn" TEXT;

CREATE UNIQUE INDEX "livros_isbn_key" ON "livros"("isbn");

PostgreSQL permite vários NULLs nesse índice único, então as duas linhas antigas sobrevivem. Em seguida, execute um backfill que atribui ISBN real a cada livro. Só numa migration posterior retire o ?, depois de medir que não resta NULL.

Em tabela grande, criar índice único pode bloquear ou consumir recursos. Uma migration customizada pode exigir estratégia específica do PostgreSQL. Use --create-only, ajuste o SQL com revisão e teste numa cópia representativa.

bash
npx prisma migrate dev --name adiciona_isbn --create-only
# revise prisma/migrations/..._adiciona_isbn/migration.sql
npx prisma migrate dev
npx prisma generate

O último comando é separado de propósito: Prisma 7 não gera Client automaticamente depois de migrate dev.

Dev cria; deploy só aplica o histórico

Os comandos pertencem a ambientes diferentes:

Comando Ambiente Comportamento
prisma migrate dev desenvolvimento Detecta mudanças, usa shadow database, cria migration, aplica e pode pedir reset.
prisma migrate status diagnóstico Compara migrations locais com registros aplicados e informa pendências.
prisma migrate deploy staging/produção Aplica migrations pendentes; não cria novas, não usa shadow database e não gera Client.
prisma db push protótipo descartável Sincroniza schema sem histórico de migration para transportar entre ambientes.

Não execute migrate dev num deploy. Ele é interativo e pode propor reset diante de drift ou conflito. O pipeline deve receber migrations já criadas e revisadas.

Um banco limpo comprova que o histórico viaja

No teste, um segundo PostgreSQL vazio recebeu as duas migrations com:

bash
npx prisma migrate deploy
2 migrations found in prisma/migrations

Applying migration 20260823013543_inicial Applying migration 20260823013634_adiciona_isbn

The following migration(s) have been applied:

migrations/ └─ 20260823013543_inicial/ └─ migration.sql └─ 20260823013634_adiciona_isbn/ └─ migration.sql

All migrations have been successfully applied.

Esse é o teste que importa: não apenas “funciona na minha base”, mas um ambiente vazio chega ao mesmo estado seguindo o histórico. Em projeto profissional, faça isso no CI e também teste upgrade com dados parecidos com os reais.

Drift é diferença entre história e realidade

Se alguém executa ALTER TABLE manualmente sem registrar uma migration, o banco e o histórico deixam de contar a mesma história. migrate dev reexecuta as migrations numa shadow database e compara o resultado, podendo pedir reset do ambiente de desenvolvimento.

Não aceite reset sem saber qual banco está na URL. O comando apaga dados do schema de desenvolvimento para reconstruí-lo. Antes de confirmar, confira host, database e ambiente. Em produção, preserve o estado, investigue a diferença e prepare uma reconciliação explícita.

Uma política útil é proibir alteração manual de estrutura fora de uma migration, exceto hotfix documentado com plano imediato de baseline ou migration equivalente. Também mantenha migrations no mesmo pull request do schema que elas implementam.

Missão: faça uma mudança que não pode ser imediata

Crie uma tabela Cliente com duas linhas e depois acrescente telefone String obrigatório. Reproduza o bloqueio de migration. Corrija em três passos: torne o campo opcional, aplique; preencha telefones distintos; retire ? numa segunda migration.

sql
SELECT COUNT(*) AS sem_telefone
FROM clientes
WHERE telefone IS NULL;

Seu critério de sucesso: o primeiro migrate falha sem alterar dados; a primeira migration contém coluna anulável; a consulta retorna zero depois do backfill; a segunda adiciona NOT NULL; um banco vazio aplica o histórico inteiro com migrate deploy.

Finalize rodando prisma migrate status e prisma generate. Depois volte ao guia de Prisma ORM 7 e confira se você consegue explicar a diferença entre schema desejado, SQL versionado, estado aplicado e Client gerado.

  • prisma migrate
  • migrations prisma
  • migrate dev
  • migrate deploy
  • postgresql
  • banco de dados

Perguntas frequentes

Qual a diferença entre migrate dev e migrate deploy?
Migrate dev detecta mudanças, cria SQL, usa shadow database e aplica no desenvolvimento. Migrate deploy apenas aplica migrations pendentes e é o comando apropriado para pipeline de staging e produção.
Prisma 7 gera Client depois de migrate dev?
Não automaticamente. Depois de alterar schema ou aplicar uma mudança que afeta a API, execute prisma generate como etapa explícita do desenvolvimento ou do build.
Posso editar uma migration já aplicada?
Evite. O checksum e o histórico precisam representar o que foi aplicado. Corrija com uma nova migration; editar o passado cria divergência entre ambientes.
Quando usar db push no lugar de migrate dev?
Db push ajuda em protótipos descartáveis porque sincroniza o schema sem criar histórico versionado. Para uma aplicação cuja estrutura precisa viajar entre ambientes, prefira migrations revisáveis.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

Todo o código deste artigo foi executado em Node 24.16.0, Prisma ORM 7.9.1, @prisma/adapter-pg 7.9.1, PostgreSQL 18.6 em postgres:18-alpine e Docker 29.5.3, e as saídas exibidas são as reais — como produzimos este conteúdo.

Fontes consultadas

  1. Prisma Migrate — visão geral — prisma.io
  2. Prisma Migrate — getting started — prisma.io
  3. Prisma CLI — migrate dev — prisma.io
  4. Prisma — deploy de mudanças do banco — prisma.io

Continue por aqui