Trabalhar diretamente com SQL é uma habilidade importante, mas projetos modernos também precisam de produtividade, segurança de tipos e uma forma organizada de evoluir o banco de dados. É nesse cenário que o Prisma ORM se destaca. Ele permite modelar tabelas, criar migrações e consultar dados com uma API tipada em TypeScript, reduzindo erros comuns e deixando o código mais simples de manter.
Neste guia, você vai aprender como usar Prisma ORM com PostgreSQL em um projeto Node.js. Vamos configurar o ambiente, criar o schema, executar migrações, inserir e consultar registros, definir relacionamentos e aplicar boas práticas para produção. Se você ainda está revisando os conceitos básicos, vale conhecer o que é PostgreSQL, entender como um ORM facilita o desenvolvimento e revisar o que é Node.js.
O que é Prisma ORM?
Prisma é um conjunto de ferramentas para acesso a bancos de dados em aplicações JavaScript e TypeScript. Seu componente principal é o Prisma Client, um cliente gerado a partir do schema da aplicação. Isso significa que o editor consegue sugerir campos, métodos e relacionamentos enquanto você programa.
O ecossistema também inclui o Prisma Migrate, responsável por criar e aplicar migrações, e o Prisma Studio, uma interface visual para consultar e editar dados durante o desenvolvimento. A documentação oficial apresenta todos os recursos e bancos compatíveis no site do Prisma.
Por que combinar Prisma e PostgreSQL?
O PostgreSQL é um banco relacional robusto, com suporte a transações, índices, JSON, constraints e recursos avançados. Já o Prisma oferece uma camada de desenvolvimento mais amigável para projetos Node.js. A combinação é interessante porque preserva a confiabilidade do banco e adiciona uma API tipada para a aplicação.
Entre os principais benefícios estão a validação de tipos em tempo de desenvolvimento, migrações versionadas, consultas mais legíveis e geração automática do cliente. Ainda assim, o Prisma não elimina a necessidade de entender banco de dados. Conceitos como chaves estrangeiras, índices e normalização continuam essenciais.
Preparando o projeto
Crie uma nova pasta e inicialize o projeto:
mkdir prisma-postgres
cd prisma-postgres
npm init -y
npm install prisma @prisma/client
npm install -D typescript tsx @types/node
npx prisma initO comando prisma init cria a pasta prisma, o arquivo schema.prisma e um arquivo .env. No ambiente de desenvolvimento, você pode iniciar o PostgreSQL localmente, usar Docker ou contratar um serviço gerenciado. Caso queira entender melhor contêineres, consulte o guia sobre Docker e para que ele serve.
Configurando a conexão
No arquivo .env, defina a variável DATABASE_URL:
DATABASE_URL="postgresql://usuario:senha@localhost:5432/loja?schema=public"Não envie esse arquivo para o repositório. Adicione .env ao .gitignore e use variáveis de ambiente diferentes em desenvolvimento, homologação e produção. O formato da URL e outras opções de conexão estão descritos na documentação do PostgreSQL no Prisma.
Criando o primeiro schema
Abra prisma/schema.prisma e defina os modelos:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
@@index([authorId])
}O campo @id define a chave primária, @unique impede e-mails duplicados e @relation representa a ligação entre usuário e post. O índice em authorId ajuda consultas por autor.
Criando a migração
Depois de salvar o schema, execute:
npx prisma migrate dev --name initEsse comando cria os arquivos SQL da migração, aplica as alterações no banco e gera o Prisma Client. Mantenha a pasta de migrações no controle de versão. Assim, a estrutura do banco evolui junto com o código e pode ser reproduzida por toda a equipe.
Inicializando o Prisma Client
Crie src/prisma.ts:
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();Em aplicações que reiniciam módulos com frequência, como ambientes de desenvolvimento com hot reload, evite criar várias instâncias do cliente. Em frameworks, siga a recomendação específica da documentação para reutilizar a conexão.
Inserindo dados
Agora crie um usuário com um post relacionado:
import { prisma } from "./prisma";
async function main() {
const user = await prisma.user.create({
data: {
name: "Marina",
email: "marina@example.com",
posts: {
create: {
title: "Meu primeiro post",
content: "Conteúdo do artigo"
}
}
},
include: { posts: true }
});
console.log(user);
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect());A propriedade include solicita que os posts relacionados sejam retornados junto com o usuário. Sem ela, o resultado contém apenas os campos do modelo principal.
Consultando registros
Para listar usuários com posts publicados:
const users = await prisma.user.findMany({
where: {
posts: {
some: { published: true }
}
},
include: {
posts: {
where: { published: true },
orderBy: { createdAt: "desc" }
}
},
orderBy: { name: "asc" }
});O Prisma oferece filtros como equals, contains, in, gt e lt. Também permite paginação, ordenação e seleção de campos. Em APIs, prefira retornar apenas os dados necessários para reduzir transferência e exposição indevida.
Atualizando e removendo dados
Uma atualização simples pode ser feita assim:
await prisma.post.update({
where: { id: 1 },
data: { published: true }
});Para remover:
await prisma.post.delete({
where: { id: 1 }
});Operações com identificadores inexistentes podem lançar exceções. Trate esses erros e converta-os em respostas adequadas na API, como HTTP 404. Para estruturar endpoints, consulte o tutorial sobre como criar uma API com Node.js.
Usando transações
Quando várias operações precisam ser concluídas juntas, use transações:
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({
data: { name: "Lucas", email: "lucas@example.com" }
});
await tx.post.create({
data: {
title: "Post transacional",
authorId: user.id
}
});
});Se uma etapa falhar, todas as alterações são revertidas. Esse comportamento é importante em cadastros, pagamentos, movimentações e outros fluxos que não podem ficar pela metade.
Prisma Studio
Durante o desenvolvimento, execute:
npx prisma studioO navegador abrirá uma interface para visualizar e editar registros. Use o Studio como ferramenta de apoio, não como substituto para validações, autorização e rotinas administrativas seguras.
Boas práticas em produção
- Use migrations em vez de alterações manuais: aplique
prisma migrate deployno processo de entrega. - Configure pool de conexões: ambientes serverless podem abrir muitas conexões simultâneas.
- Crie índices com base nas consultas reais: índices demais também aumentam o custo de escrita.
- Selecione apenas campos necessários: use
selectpara limitar o resultado. - Não exponha erros internos: registre detalhes no servidor e envie mensagens seguras ao cliente.
- Valide entradas: o ORM ajuda nos tipos, mas não substitui validação de dados recebidos.
- Monitore consultas lentas: analise planos de execução e uso de índices quando necessário.
Quando usar SQL direto?
O Prisma cobre grande parte das operações comuns, mas há casos em que SQL direto pode ser mais adequado: relatórios complexos, consultas analíticas, recursos específicos do PostgreSQL ou otimizações muito específicas. Nesses casos, utilize consultas parametrizadas e revise cuidadosamente a segurança.
O mais importante é não tratar ORM e SQL como adversários. O ORM melhora produtividade e consistência, enquanto o conhecimento de SQL permite diagnosticar desempenho e modelar corretamente os dados.
Conclusão
Usar Prisma ORM com PostgreSQL oferece uma experiência produtiva para projetos Node.js e TypeScript. O schema centraliza a modelagem, as migrações registram a evolução do banco e o cliente gerado fornece consultas tipadas e fáceis de descobrir no editor.
Comece com um modelo pequeno, mantenha as migrações versionadas e adicione relacionamentos aos poucos. Em produção, dê atenção especial a conexões, índices, transações, validação e observabilidade. Com esses cuidados, Prisma e PostgreSQL formam uma base sólida para APIs e aplicações web modernas.




