<h2>Introdução ao Prisma ORM</h2>
<p>O Prisma é um ORM (Object-Relational Mapping) moderno para Node.js que resolve um dos maiores desafios da programação backend: gerenciar dados de forma segura e com type safety completo. Diferentemente de ORMs tradicionais como Sequelize ou TypeORM, o Prisma oferece uma abordagem schema-first, onde você define seu modelo de dados uma única vez e tudo mais é gerado automaticamente. Isso elimina redundância e reduz drasticamente bugs relacionados a tipos de dados.</p>
<p>Neste artigo, você aprenderá a configurar Prisma, modelar seus dados, executar migrations e escrever queries type-safe. Vamos direto ao essencial, sem teorias desnecessárias.</p>
<h2>Configuração Inicial e Modelagem de Dados</h2>
<h3>Instalação e Setup</h3>
<p>Comece criando um projeto Node.js e instalando Prisma:</p>
<pre><code class="language-bash">npm init -y
npm install @prisma/client
npm install -D prisma
npx prisma init</code></pre>
<p>Isso cria um arquivo <code>.env</code> e um diretório <code>prisma/</code> com o arquivo <code>schema.prisma</code>. Configure a variável de ambiente com seu banco de dados:</p>
<pre><code class="language-env">DATABASE_URL="postgresql://user:password@localhost:5432/meu_banco"</code></pre>
<h3>Definindo Modelos com Prisma Schema</h3>
<p>O Prisma Schema é onde tudo começa. Ele define sua estrutura de dados em uma sintaxe limpa e intuitiva. Veja um exemplo real:</p>
<pre><code class="language-prisma">// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
createdAt DateTime @default(now())
posts Post[] // Relação um-para-muitos
}
model Post {
id Int @id @default(autoincrement())
title String
content String
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
comments Comment[]
}
model Comment {
id Int @id @default(autoincrement())
text String
postId Int
post Post @relation(fields: [postId], references: [id])
}</code></pre>
<p>Cada modelo mapeia diretamente para uma tabela no banco de dados. Os atributos <code>@id</code>, <code>@unique</code> e <code>@default</code> definem constraints e comportamentos padrão. As relações (como <code>posts Post[]</code>) permitem navegação bidirecional tipada entre entidades.</p>
<h2>Migrations: Sincronizando Banco e Schema</h2>
<h3>Criando e Executando Migrations</h3>
<p>Migrations são a forma como Prisma controla versões de seu banco de dados. Após modificar o schema, execute:</p>
<pre><code class="language-bash">npx prisma migrate dev --name nome_da_migracao</code></pre>
<p>Isso cria um arquivo SQL em <code>prisma/migrations/</code> e aplica no banco automaticamente. Por exemplo, adicionar um novo campo:</p>
<pre><code class="language-prisma">model User {
id Int @id @default(autoincrement())
email String @unique
name String
phone String? // Novo campo, opcional
createdAt DateTime @default(now())
posts Post[]
}</code></pre>
<p>Execute <code>npx prisma migrate dev --name add_phone_to_user</code> e o Prisma gera:</p>
<pre><code class="language-sql">ALTER TABLE "User" ADD COLUMN "phone" TEXT;</code></pre>
<p>Para sincronizar sem criar nova migração (desenvolvimento), use:</p>
<pre><code class="language-bash">npx prisma db push</code></pre>
<h3>Reset e Replicação</h3>
<p>Em desenvolvimento, você pode resetar o banco:</p>
<pre><code class="language-bash">npx prisma migrate reset</code></pre>
<p>Isso desfaz todas as migrations, recria o schema do zero e executa seeds. Para produção, sempre revise as migrations antes de executar.</p>
<h2>Queries Tipadas e Operações com Prisma Client</h2>
<h3>Operações CRUD Básicas</h3>
<p>O Prisma Client fornece métodos type-safe para queries. TypeScript infere os tipos automaticamente:</p>
<pre><code class="language-typescript">import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// CREATE
const newUser = await prisma.user.create({
data: {
email: 'joao@example.com',
name: 'João Silva'
}
});
// READ
const user = await prisma.user.findUnique({
where: { email: 'joao@example.com' },
include: { posts: true } // Carrega relacionamentos
});
// UPDATE
const updated = await prisma.user.update({
where: { id: 1 },
data: { name: 'João Updated' }
});
// DELETE
await prisma.user.delete({
where: { id: 1 }
});
// LISTAR COM FILTROS
const recentPosts = await prisma.post.findMany({
where: {
published: true,
createdAt: {
gte: new Date('2024-01-01')
}
},
orderBy: { createdAt: 'desc' },
take: 10
});</code></pre>
<h3>Queries Avançadas e Relações</h3>
<p>Prisma permite queries complexas com type safety total. Veja operações mais sofisticadas:</p>
<pre><code class="language-typescript">// Agregações
const totalPosts = await prisma.post.count({
where: { published: true }
});
// Nested writes (criar pai e filho simultaneamente)
const userWithPost = await prisma.user.create({
data: {
email: 'maria@example.com',
name: 'Maria',
posts: {
create: [
{ title: 'Primeiro Post', content: 'Conteúdo aqui' },
{ title: 'Segundo Post', content: 'Mais conteúdo' }
]
}
},
include: { posts: true }
});
// Transações para múltiplas operações atomicamente
await prisma.$transaction([
prisma.post.deleteMany({ where: { authorId: 5 } }),
prisma.user.delete({ where: { id: 5 } })
]);
// Raw queries quando necessário
const users = await prisma.$queryRaw`
SELECT * FROM "User" WHERE email LIKE ${%example%}
`;</code></pre>
<p>O IntelliSense do TypeScript autocompleta campos e relações, evitando erros em tempo de desenvolvimento. Se você escrever <code>prisma.user.findMany({ where: { invalidField: true } })</code>, TypeScript avisa imediatamente.</p>
<h2>Boas Práticas e Otimização</h2>
<h3>Gerenciamento de Conexões</h3>
<p>Crie uma instância única do Prisma Client e reutilize-a:</p>
<pre><code class="language-typescript">// lib/prisma.ts
export const prisma = new PrismaClient();
// Importar em qualquer arquivo
import { prisma } from './lib/prisma';</code></pre>
<p>Para aplicações serverless, considere usar pool de conexões:</p>
<pre><code class="language-env">DATABASE_URL="postgresql://user:pass@localhost/db?schema=public"</code></pre>
<h3>Seleção Eficiente de Campos</h3>
<p>Use <code>select</code> para trazer apenas os dados necessários, reduzindo payload:</p>
<pre><code class="language-typescript">const users = await prisma.user.findMany({
select: {
id: true,
email: true,
name: true,
posts: {
select: { title: true }
}
}
});</code></pre>
<h3>Tratamento de Erros</h3>
<p>Prisma lança exceções tipadas. Trate-as apropriadamente:</p>
<pre><code class="language-typescript">import { Prisma } from '@prisma/client';
try {
await prisma.user.create({
data: { email: 'duplicado@example.com', name: 'Teste' }
});
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === 'P2002') {
console.log('Email já existe');
}
}
}</code></pre>
<h2>Conclusão</h2>
<p>Você aprendeu que <strong>Prisma oferece type safety automático</strong>, eliminando erros de tipos em queries — algo que ORMs antigos não fazem nativamente. Segundo, <strong>migrations são simples e versionadas</strong>, facilitando colaboração em equipe e deploy seguro. Terceiro, <strong>a sintaxe é intuitiva e produtiva</strong>, reduzindo boilerplate significativamente em relação a SQL puro ou ORMs concorrentes.</p>
<p>Prisma transforma a forma como você trabalha com dados, tornando o código mais confiável e mantível. Pratique criando um projeto pequeno e explore a documentação oficial para casos de uso avançados.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.prisma.io/docs/" target="_blank" rel="noopener noreferrer">Prisma Documentation - Official Docs</a></li>
<li><a href="https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference" target="_blank" rel="noopener noreferrer">Prisma Schema Reference</a></li>
<li><a href="https://www.prisma.io/docs/concepts/components/prisma-client" target="_blank" rel="noopener noreferrer">Prisma Client CRUD Operations</a></li>
<li><a href="https://www.prisma.io/docs/concepts/components/prisma-migrate" target="_blank" rel="noopener noreferrer">Database Migrations Guide</a></li>
<li><a href="https://www.prisma.io/docs/concepts/more/develop-the-prisma-orm" target="_blank" rel="noopener noreferrer">Prisma with TypeScript Best Practices</a></li>
</ul>