Pular para conteúdo

Aula 19 - ORM Prisma / TypeORM com Migrações Rígidas 🗄️

Objetivo Pedagógico

Objetivo: Modelagem relacional de alta fidelidade com Prisma ORM, consultas estritamente tipadas, controle de concorrência e migrações reproduzíveis.


📑 1. Fundamentos Teóricos & Análise Técnica

A camada de persistência de dados em backends corporativos exige garantias estritas de integridade referencial, controle de versão do esquema e segurança de tipos (type safety). O Prisma ORM revolucionou esse ecossistema ao introduzir um modelo declarativo baseado em um arquivo de esquema (schema.prisma) que serve como fonte única da verdade para a geração automatizada de migrações e do cliente tipado.

Diferenças cruciais em relação aos ORMs legados baseados em Active Record: 1. Geração de Cliente Sob Demanda (Prisma Client): A cada alteração no esquema, o Prisma gera uma biblioteca TypeScript local com autocomplete total das tabelas, campos e relações, tornando impossível realizar queries em colunas inexistentes em tempo de compilação. 2. Motor de Migrações Rígidas (Prisma Migrate): Gera arquivos SQL declarativos e versionados em ordem sequencial no Git, com validação de consistência antes da execução em produção (prisma migrate deploy). 3. Proteção contra SQL Injection: Todas as queries geradas são parametrizadas de fábrica, com suporte transparente a transações atômicas com prisma.$transaction().

📐 Arquitetura Conceitual & Diagrama de Fluxo

flowchart LR
    Schema["schema.prisma (Modelo Declarativo)"] --> Migrate["Prisma Migrate (Gera Migrações SQL)"]
    Schema --> ClientGen["Prisma Client Generator"]
    Migrate --> DB["PostgreSQL / MySQL em Produção"]
    ClientGen --> TS["Cliente TypeScript com Autocomplete e Zero Erros de Tipo"]
    TS --> App["Código da Aplicação"]
    style Schema fill:#e1f5fe,stroke:#01579b
    style Migrate fill:#fff3e0,stroke:#e65100
    style TS fill:#e8f5e9,stroke:#2e7d32

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Esquema Declarativo: Modelagem de tabelas, relações 1:1, 1:N, N:N e índices em formato limpo. - Segurança de Tipos em Consultas: O retorno de cada consulta (findUnique, findMany) possui tipo estrito baseado no objeto select ou include. - Transações Interativas: Uso de prisma.$transaction(async tx => ...) para operações bancárias ou comerciais críticas. - Pipelines de CI/CD Reproduzíveis: Execução determinística de migrações sem prompts interativos em ambientes produtivos.


🛠️ 2. Implementação Prática em Prisma ORM e Modelagem Relacional

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// schema.prisma (Definição de Modelos e Relações)
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        String   @id @default(uuid())
  email     String   @unique
  name      String
  createdAt DateTime @default(now())
  orders    Order[]

  @@index([email])
  @@map("users")
}

model Order {
  id          String   @id @default(uuid())
  totalAmount Decimal  @db.Decimal(10, 2)
  status      String   @default("PENDING")
  userId      String
  user        User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  createdAt   DateTime @default(now())

  @@map("orders")
}

💡 Análise Passo a Passo do Código

  1. Mapeamento com @@map: Garante nomenclatura em snake_case no banco de dados (users, orders) enquanto preserva convenções PascalCase no TypeScript.
  2. Integridade Referencial: onDelete: Cascade garante a remoção consistente de pedidos órfãos ao excluir um usuário.
  3. Índices Otimizados: @@index([email]) cria índice B-Tree automaticamente na base para acelerar consultas frequentes.

🎯 3. Próximos Passos & Sequência Didática