Galho 6 — ORMs e banco de dados: Plano de Execução
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Criar 10 notas atômicas + 1 MOC em 03-Dominios/Node/ORMs e banco de dados/ cobrindo os principais ORMs do ecossistema Node.js (Sequelize, Prisma, TypeORM, Drizzle), padrões de banco de dados (N+1, migrations, transações, paginação), e podar as seções correspondentes do tronco Node.js.md. Contexto: maio de 2026 — Prisma v6+, Drizzle ORM consolidado, Node 22 LTS, TypeScript nativo.
Architecture: Cada nota é um arquivo Markdown independente em 03-Dominios/Node/ORMs e banco de dados/. O MOC serve como ponto de entrada com rotas alternativas. O tronco é podado ao final com callouts de migração.
Tech Stack: Obsidian Flavored Markdown, frontmatter YAML, wikilinks [[]], callouts [!abstract], dataview query no MOC. ORMs cobertos: Sequelize v7, Prisma v6, TypeORM v0.3, Drizzle ORM v0.30+. Runtime: Node 22 LTS + TypeScript nativo. Bancos: PostgreSQL (primário), MySQL/SQLite (menção).
REGRAS CRÍTICAS PARA O AGENTE EXECUTOR
⚠️ ONE commit per note, NOT bundled. Cada task = 1 nota = 1 commit dedicado. Commitar múltiplas notas em 1 commit é violação do workflow.
⚠️ Nenhuma nota abaixo do mínimo de linhas declarado. Abaixo do mínimo a nota perde profundidade para o nível senior exigido. O mínimo é piso, não teto.
⚠️ “Em entrevista” obrigatoriamente 3+ sentenças em inglês interligadas. Proibido one-liner.
⚠️ Sem Co-Authored-By em commits. Mensagens seguem o formato:
feat(node/g6): add <número> - <título>.⚠️ Self-check antes de cada commit — ver checklist na seção Self-Check abaixo.
⚠️ Informações atualizadas para maio de 2026: Prisma v6 (não v5), Drizzle v0.30+, Node 22 LTS, TypeScript 5.5+. Nunca referenciar APIs deprecadas como default atual.
Self-Check (executar antes de cada commit de nota)
[ ] Frontmatter completo: title, created, updated, type, status, progresso, publish, tags, aliases (quando aplicável)
[ ] TL;DR callout [!abstract] presente com conteúdo denso (> 3 linhas)
[ ] Contagem de linhas >= mínimo declarado para esta nota
[ ] "Em entrevista" tem 3+ sentenças em inglês (não one-liner)
[ ] "Vocabulário PT→EN" tem >= 6 termos com tradução
[ ] Cada armadilha tem: (a) descrição + (b) código-problema + (c) fix
[ ] "Como funciona" tem >= 3 subsecções (headings ###)
[ ] Número de exemplos de código >= mínimo declarado para esta nota
[ ] Wikilinks para [[Node.js]] e [[ORMs e banco de dados]] (MOC) presentes
[ ] "Fontes" com pelo menos 1 link oficial da ferramenta principal
Estrutura de arquivos
Criar:
03-Dominios/Node/ORMs e banco de dados/
├── ORMs e banco de dados.md (MOC — Task 1)
├── 01 - Panorama de ORMs.md (Task 2)
├── 02 - Sequelize - queries e associações.md (Task 3)
├── 03 - Prisma - schema-first e type safety.md (Task 4)
├── 04 - TypeORM - decorators ao estilo JPA.md (Task 5)
├── 05 - Drizzle - ORM lightweight e type-safe.md (Task 6)
├── 06 - N+1 queries - detecção e DataLoader.md (Task 7)
├── 07 - Migrations e versionamento de schema.md (Task 8)
├── 08 - Transações - gerenciamento manual vs automático.md (Task 9)
├── 09 - Paginação - offset, cursor e keyset.md (Task 10)
└── 10 - Cheatsheet e decision tree de ORMs.md (Task 11)
Modificar:
03-Dominios/JavaScript/Backend/Node.js.md (poda: 2 seções → callouts — Task 12)
03-Dominios/Node/index.md (adicionar galho 6 — Task 12)
Task 1: MOC — ORMs e banco de dados
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/ORMs e banco de dados.md
Commit: feat(node/g6): add MOC - ORMs e banco de dados
- Step 1: Criar o arquivo MOC
Criar 03-Dominios/Node/ORMs e banco de dados/ORMs e banco de dados.md com:
---
title: "ORMs e banco de dados"
created: 2026-05-10
updated: 2026-05-10
type: moc
status: growing
publish: true
tags:
- node
- orm
- banco-de-dados
- moc
aliases:
- ORMs Node
- Galho 6 - ORMs
---
# ORMs e banco de dadosConteúdo do MOC deve incluir:
-
Callout
[!abstract] TL;DRcobrindo o galho (4+ linhas): o que é um ORM, os 4 principais do ecossistema Node (Sequelize, Prisma, TypeORM, Drizzle) e seus posicionamentos em 2026, e os padrões críticos (N+1, migrations, transações, paginação). -
Seção
## Sobre este galhocom:- Descrição clara do escopo (2-3 parágrafos)
- Pré-requisitos:
[[Frameworks e arquitetura]](galho 4),[[Node.js]](tronco) - Audiência primária: dev senior prep entrevista internacional
- Audiência secundária: dev integrando banco em API Node existente
-
Seção
## Comece por aqui — trilha completa (10 notas)organizada em blocos:- Bloco A — Visão geral:
[[01 - Panorama de ORMs]] - Bloco B — Os 4 ORMs: notas 02-05
- Bloco C — Padrões críticos: notas 06-09
- Bloco D — Fechamento:
[[10 - Cheatsheet e decision tree de ORMs]]
- Bloco A — Visão geral:
-
Seção
## Rotas alternativascom pelo menos 3 rotas:- Rota entrevista (foco nos 4 ORMs + N+1 + decision tree)
- Rota migrations (07 → 08 → 10)
- Rota performance/N+1 (06 → 09 → 10)
- Rota onboarding Prisma (03 → 07 → 08 → 09)
-
Seção
## Todas as notascom query dataview:TABLE status, updated FROM "03-Dominios/Node/ORMs e banco de dados" WHERE type = "concept" SORT file.name ASC -
Seção
## Veja tambémcom wikilinks para:[[Node.js]],[[Frameworks e arquitetura]], galhos anteriores,[[03-Dominios/Node/index|Node.js (MOC central)]].
Mínimo de linhas: 80
Task 2: Nota 01 — Panorama de ORMs
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/01 - Panorama de ORMs.md
Commit: feat(node/g6): add 01 - Panorama de ORMs
Frontmatter:
title: "Panorama de ORMs"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- sequelize
- prisma
- typeorm
- drizzle
publish: falseConteúdo mínimo (340+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Os 4 ORMs e seus posicionamentos em 2026 — Sequelize (battle-tested, callback-era), Prisma (schema-first, DX excelente, v6 estável), TypeORM (decorators, similar ao JPA, popular em NestJS), Drizzle (lightweight, SQL-first, type-safe, favorito de 2024-2025). -
Seção
## O que éexplicando:- O que é um ORM e para que serve
- A diferença entre ORM, query builder e SQL puro
- Por que escolher um ORM em Node.js
-
Seção
## Como funcionacom subsecções:Eixos de comparação
Tabela Markdown comparando os 4 ORMs nos eixos:
- Paradigma (schema-first, code-first, SQL-first)
- Type safety (gerada, manual, nativa)
- Migration strategy
- Performance overhead
- Suporte a edge runtimes (Cloudflare Workers, Vercel Edge)
- Maturidade/popularidade em 2026
- Ideal para (projetos novos, legacy, NestJS, edge)
Sequelize
Parágrafo + snippets:
- Surgiu na era do callback, amadureceu com Promises
- v7 (2025): melhor suporte a TypeScript, removed deprecated methods
- Ainda popular em projetos legacy e empresas que não migraram
- Exemplo de model + query básica
Prisma
Parágrafo + snippets:
- v6 (2025): suporte a edge runtimes, Prisma Accelerate GA, melhor performance
- Schema declarativo em
schema.prisma→ gera types TypeScript automaticamente - Prisma Client, Prisma Migrate, Prisma Studio
- Exemplo de schema.prisma + query
TypeORM
Parágrafo + snippets:
- Decorators style à la JPA/Hibernate
- Integração nativa com NestJS (
@nestjs/typeorm) - v0.3+ com melhorias de type safety
- Exemplo de Entity + Repository
Drizzle ORM
Parágrafo + snippets:
- SQL-first: você escreve TypeScript que parece SQL
- Zero-runtime overhead: sem proxies, sem magic
- Excelente para edge runtimes
- Drizzle Studio (similar ao Prisma Studio)
- Exemplo de schema + query
-
Seção
## Quando usarcom decision tree textual:- NestJS enterprise → TypeORM ou Prisma
- Edge runtime (Cloudflare Workers) → Drizzle
- Projeto legacy com Sequelize → upgrade v7, não migrar
- Novo projeto Node.js → Prisma v6 (DX) ou Drizzle (performance/edge)
- Equipe familiarizada com SQL → Drizzle
- Equipe vinda do Java/Spring → TypeORM
-
Seção
## Armadilhas comuns(3+ armadilhas):- Escolher ORM por popularidade e não por fit (edge vs server)
- Assumir que Prisma gerado é always type-safe (raw queries não são)
- TypeORM
synchronize: trueem produção
-
Seção
## Em entrevistacom:- Parágrafo em inglês (4+ sentenças) sobre como escolher entre os 4 ORMs
- Vocabulário PT→EN (8+ termos): schema, migration, eager loading, lazy loading, query builder, type safety, code-first, schema-first, etc.
-
Seção
## Fontescom links para docs oficiais de todos os 4 ORMs. -
Seção
## Veja tambémcom wikilinks para as 4 notas individuais + MOC.
Mínimo de código: 6 snippets TypeScript (ao menos 1 por ORM + tabela comparativa)
Task 3: Nota 02 — Sequelize — queries e associações
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/02 - Sequelize - queries e associações.md
Commit: feat(node/g6): add 02 - Sequelize - queries e associações
Frontmatter:
title: "Sequelize - queries e associações"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- sequelize
- postgres
- banco-de-dados
publish: falseConteúdo mínimo (340+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Sequelize v7, ORM battle-tested, suporte TypeScript melhorado, modelo baseado emdefine/decorators, associations (HasMany, BelongsTo, BelongsToMany), eager loading comincludepara evitar N+1. Em 2026 ainda relevante para projetos existentes mas Prisma/Drizzle são preferidos para novos projetos. -
Seção
## O que é: Sequelize como ORM Node.js mais antigo (2011), suporte a PostgreSQL, MySQL, MariaDB, SQLite, SQL Server. -
Seção
## Como funcionacom subsecções:Definição de models
- Model com
sequelize-typescript(decorators) - Tipos de colunas:
DataTypes.STRING,DataTypes.INTEGER,DataTypes.JSONB,DataTypes.DATE, etc. - Validações inline (
@Column({ validate: { isEmail: true } }))
Associations (relacionamentos)
@HasMany,@BelongsTo,@HasOne,@BelongsToMany- Como configurar foreign keys
- Associações polimórficas (quando evitar)
Queries CRUD
findAll,findOne,findByPk,findOrCreatecreate,update,destroy,upsert- Operadores (
Op.eq,Op.gte,Op.like,Op.in,Op.or) - Ordenação, limit, offset
Eager loading e include
include: [Model]básicoincludecomwhere,attributes,required(INNER vs LEFT JOIN)includeaninhado (3 níveis max antes de problema de performance)- Evitar N+1 com eager loading (ponte para Task 7)
Transações
sequelize.transaction(async (t) => { ... })- Managed vs unmanaged transactions
- Ponteiro para Task 9
Hooks e lifecycle
beforeCreate,afterCreate,beforeUpdate,beforeDestroy- Caso de uso: hash de senha, audit log
- Model com
-
Seção
## Quando usar: projetos legacy, equipes que já conhecem, quando não compensa migrar. -
Seção
## Armadilhas comuns(4+ armadilhas com código):- Lazy loading acidental (N+1 — com código antes/depois)
includesemrequired: falsegerando INNER JOIN silenciosodestroy()semwheredeletando tudoOp.likeem produção com pattern%texto%(full scan)timestamps: false+paranoid: trueconflito
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre quando usar Sequelize vs alternativas, eager loading para evitar N+1, estratégia de migrations. -
Seção
## Vocabulário PT→EN(8+ termos): associação, carregamento antecipado, carregamento preguiçoso, gancho de ciclo de vida, transação gerenciada, etc. -
Seção
## Fontes: links para docs oficiais Sequelize v7 + sequelize-typescript.
Mínimo de código: 8 snippets TypeScript
Task 4: Nota 03 — Prisma — schema-first e type safety
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/03 - Prisma - schema-first e type safety.md
Commit: feat(node/g6): add 03 - Prisma - schema-first e type safety
Frontmatter:
title: "Prisma - schema-first e type safety"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- prisma
- type-safety
- banco-de-dados
publish: falseConteúdo mínimo (380+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Prisma v6 em 2026 — schema declarativo emschema.prisma, Prisma Client gerado automaticamente com types TypeScript precisos, Prisma Migrate para versionamento, Prisma Studio para inspeção visual. Suporte a edge runtimes com Prisma Accelerate. Melhor DX entre os ORMs Node, curva de aprendizado menor para devs TypeScript. -
Seção
## O que é: Prisma como toolkit de banco de dados (não só ORM) — três camadas: Prisma Client, Prisma Migrate, Prisma Studio. -
Seção
## Como funcionacom subsecções:Schema Prisma
- Sintaxe de
schema.prisma:datasource,generator,model,enum - Tipos de campo:
String,Int,Boolean,DateTime,Json,Bytes - Modificadores:
?(opcional),[](array) - Relações:
@relation, campos de relação explícitos - Exemplo completo com 2-3 models relacionados
Prisma Client — CRUD
findMany,findFirst,findUnique,findUniqueOrThrowcreate,createMany,update,updateMany,upsert,delete,deleteManyselectvsinclude— diferença importantewherecom filtros compostos (AND,OR,NOT)orderBy,take,skip,cursor
Relações e includes
includecom relações aninhadasselectpara projection granular (evitar over-fetching)_countpara contar registros relacionados sem carregarconnect/disconnect/setpara gerenciar relações nocreate/update
Prisma Migrate
prisma migrate devvsprisma migrate deploy- Migration files gerados automaticamente
- Squash de migrations antigas
prisma db pushpara prototipagem (sem migration files)- Diferença entre
deveprodworkflow
Raw queries e escape de type safety
$queryRawe$executeRawpara SQL literalPrisma.sqltemplate tag para evitar SQL injection- Quando usar raw: queries complexas, window functions, CTEs
Prisma Accelerate (v6)
- Connection pooling global para edge
- Cache em CDN para queries lentas
- Quando faz sentido ativar
- Sintaxe de
-
Seção
## Quando usar: novo projeto com TypeScript, edge runtime, equipe que valoriza DX, migrations versionadas automáticas. -
Seção
## Armadilhas comuns(4+ armadilhas com código):findManysem paginação em tabelas grandes (OOM)includeaninhado profundo causando N+1 (explicar o caso)$queryRawcom interpolação string (SQL injection)prisma migrate deployem dev (nunca em prod sem teste)- Não versionar
schema.prismano git (sempre versionar)
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre Prisma, schema-first, type safety gerada, vs TypeORM/Drizzle. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: links para docs Prisma v6 + changelog de breaking changes v5→v6.
Mínimo de código: 10 snippets (prisma schema + TypeScript)
Task 5: Nota 04 — TypeORM — decorators ao estilo JPA
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/04 - TypeORM - decorators ao estilo JPA.md
Commit: feat(node/g6): add 04 - TypeORM - decorators ao estilo JPA
Frontmatter:
title: "TypeORM - decorators ao estilo JPA"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- typeorm
- nestjs
- banco-de-dados
publish: falseConteúdo mínimo (320+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): TypeORM com decorators (@Entity,@Column,@OneToMany), estilo similar ao JPA/Hibernate — familiar para devs Java. Integração nativa com NestJS via@nestjs/typeorm. Repository pattern built-in. Em 2026, escolha válida para projetos NestJS enterprise mas Prisma v6 compete no mesmo espaço com melhor DX. -
Seção
## O que é: TypeORM origem, motivação (trazer JPA para Node.js), posição em 2026. -
Seção
## Como funcionacom subsecções:Entities e decorators
@Entity,@Column,@PrimaryGeneratedColumn,@CreateDateColumn,@UpdateDateColumn@Index,@Unique- Tipos de coluna TypeORM e mapeamento para DB
- Exemplo de entity completa com PostgreSQL
Relacionamentos
@OneToOne,@OneToMany,@ManyToOne,@ManyToMany@JoinColumn,@JoinTable- Diferença entre owning side e inverse side
- Lazy vs eager loading (
{ eager: true }vs relations no find)
Repository pattern
getRepository(Entity)vsDataSource.manager- Custom repositories:
extend Repository<Entity> find,findOne,findOneBy,save,remove,delete- Query options:
where,order,take,skip,relations
QueryBuilder
- Quando usar QueryBuilder vs find methods
createQueryBuilder('alias').leftJoinAndSelect(...).where(...).getMany()- Subqueries, CTEs (quando fugir para QueryBuilder)
- Contagem com
getCount
Integração com NestJS
TypeOrmModule.forRoot(config)eTypeOrmModule.forFeature([Entity])@InjectRepository(Entity)nos services- DataSource vs EntityManager
Migrations com TypeORM
typeorm migration:generateetypeorm migration:run- Diferença de
synchronize: true(dev) vs migrations (prod)
-
Seção
## Quando usar: NestJS enterprise, equipe vindo de Java, projetos que precisam do Repository pattern explícito. -
Seção
## Armadilhas comuns(4+ armadilhas com código):synchronize: trueem produção (NUNCA)- N+1 silencioso com lazy loading
save()fazendo SELECT antes de INSERT (useinsert()para bulk)- Circular dependency entre entities
-
Seção
## Em entrevista: 4+ sentenças em inglês comparando TypeORM com JPA, quando preferir sobre Prisma, pattern com NestJS. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: links TypeORM v0.3 docs + NestJS TypeORM guide.
Mínimo de código: 8 snippets TypeScript
Task 6: Nota 05 — Drizzle — ORM lightweight e type-safe
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/05 - Drizzle - ORM lightweight e type-safe.md
Commit: feat(node/g6): add 05 - Drizzle - ORM lightweight e type-safe
Frontmatter:
title: "Drizzle - ORM lightweight e type-safe"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- drizzle
- type-safety
- edge
- banco-de-dados
publish: falseConteúdo mínimo (320+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Drizzle ORM v0.30+ — SQL-first, zero overhead de runtime, TypeScript-native, excelente para edge runtimes (Cloudflare Workers, Vercel Edge). Cresceu muito em adoção em 2024-2025. Drizzle Kit para migrations. Drizzle Studio para inspeção. Preferido quando performance e edge são prioridades. -
Seção
## O que é: Drizzle como “SQL com superpowers TypeScript” — filosofia SQL-first vs ORM-first. -
Seção
## Como funcionacom subsecções:Schema definition
pgTable,text,integer,boolean,timestamp,jsonb,uuidprimaryKey,notNull,default,referencespara FK- Exemplo de schema completo para PostgreSQL com 2-3 tables
Queries — select
db.select().from(table).where(eq(table.col, val)).limit(n)leftJoin,innerJoinexplícitos (diferença de outros ORMs)- Operadores:
eq,ne,gt,lt,gte,lte,and,or,inArray,like,ilike,isNull orderBy,groupBy,having
Queries — mutations
db.insert(table).values({ ... })eonConflictDoUpdatedb.update(table).set({ ... }).where(...)db.delete(table).where(...)- Retornando valores com
.returning()
Relations (Drizzle ORM relations API)
relations()para definir relações sem FK explícitadb.query.table.findMany({ with: { related: true } })— eager loading- Diferença entre SQL join e relations API
Drizzle Kit — migrations
drizzle-kit generate→ gera SQL migrationsdrizzle-kit migrate→ aplicadrizzle-kit studio→ Drizzle Studio
Edge runtimes
- Por que Drizzle funciona em edge (sem
netmodule) neon-serverless,@libsql/clientpara Turso,postgres.js- Exemplo com Cloudflare Workers + Neon
-
Seção
## Quando usar: edge runtimes, performance crítica, equipe que gosta de SQL, projetos novos com TypeScript. -
Seção
## Armadilhas comuns(3+ armadilhas com código):- Confundir SQL joins com relations API (diferentes trade-offs)
.all()vs.get()— diferença sutil- Usar Drizzle sem connection pooling em serverless (usar pool externo)
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre Drizzle vs Prisma, SQL-first philosophy, edge runtime advantage. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: links para Drizzle docs + Drizzle Kit docs.
Mínimo de código: 8 snippets TypeScript
Task 7: Nota 06 — N+1 queries — detecção e DataLoader
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/06 - N+1 queries - detecção e DataLoader.md
Commit: feat(node/g6): add 06 - N+1 queries - detecção e DataLoader
Frontmatter:
title: "N+1 queries - detecção e DataLoader"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- performance
- n-mais-um
- dataloader
- graphql
- banco-de-dados
publish: falseConteúdo mínimo (340+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): N+1 é o problema de performance mais comum com ORMs. Ocorre quando buscamos N entidades e fazemos 1 query adicional por entidade para buscar relacionamentos. Solução: eager loading (include/join) para REST, DataLoader para GraphQL (batching + deduplication). Todos os ORMs sofrem; a solução varia. -
Seção
## O que é: definição precisa de N+1, por que é silencioso, como identificar nos logs de query. -
Seção
## Como funcionacom subsecções:O problema — exemplo em cada ORM
- Sequelize N+1 com lazy loading
- Prisma N+1 (mais difícil de ocorrer, mas possível com relações aninhadas em loops)
- TypeORM N+1 com lazy relations
- Drizzle: por ser SQL-first, N+1 é mais explícito
Solução com eager loading
- Sequelize:
include: [{ model: Related }](gera JOIN) - Prisma:
include: { related: true }vsselect: { related: { select: {...} } } - TypeORM:
relations: ['related']no find, ou QueryBuilder comleftJoinAndSelect - Drizzle:
leftJoinexplícito no SQL
DataLoader pattern
- O que é DataLoader (Facebook/Meta) — batch + deduplicate
- Como instanciar:
new DataLoader(async (ids) => { ... }) - Regra dos 3: o batch function deve retornar array na mesma ordem e tamanho dos IDs
- Exemplo completo: GraphQL resolver com DataLoader
- DataLoader por request (instanciar no contexto, não como singleton)
- DataLoader com Prisma e com TypeORM
Detecção em produção
- Ativar query logging nos ORMs
- Sequelize:
logging: console.log - Prisma:
log: ['query'] - TypeORM:
logging: 'all' - Drizzle:
logger: true - OpenTelemetry traces para detectar queries repetidas (ponte para galho 5)
-
Seção
## Quando usar(contexto de escolha de estratégia):- REST: sempre eager loading
- GraphQL: DataLoader é obrigatório em resolvers de relações
- Batch jobs: eager loading com chunks (10k registros de cada vez)
-
Seção
## Armadilhas comuns(4+ armadilhas com código):- DataLoader como singleton global (vazamento entre requests)
- Eager loading em tabela com milhões de registros (OOM)
includecircular causando stack overflow- DataLoader batch function retornando na ordem errada (bug silencioso)
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre N+1, como detectar, DataLoader pattern, eager loading trade-offs. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: link para docs do DataLoader (npm/GitHub) + artigos sobre N+1 em cada ORM.
Mínimo de código: 8 snippets TypeScript (incluindo DataLoader completo)
Task 8: Nota 07 — Migrations e versionamento de schema
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/07 - Migrations e versionamento de schema.md
Commit: feat(node/g6): add 07 - Migrations e versionamento de schema
Frontmatter:
title: "Migrations e versionamento de schema"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- migrations
- schema
- banco-de-dados
publish: falseConteúdo mínimo (320+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Migrations são o controle de versão do schema do banco. Cada ORM tem sua abordagem: Sequelize CLI, Prisma Migrate, TypeORM CLI, Drizzle Kit. Regra fundamental: nunca usarsynchronize: trueem produção. Em 2026, Prisma Migrate é considerado o mais ergonômico; para multi-ORM, Flyway/Liquibase são alternativas portáveis. -
Seção
## O que é: o problema que migrations resolve, analogia comgitpara código. -
Seção
## Como funcionacom subsecções:Migrations com Sequelize
sequelize-cli:npx sequelize migration:generate,migrate,undo- Estrutura de um arquivo de migration (up/down)
- Tabela
SequelizeMetacomo controle - Seeder vs migration
Migrations com Prisma Migrate
prisma migrate dev(dev + shadow database)prisma migrate deploy(prod, sem shadow)prisma migrate reset(dev only — NUNCA em prod)- Estrutura da pasta
prisma/migrations/ - Baseline de schema existente (
prisma migrate baseline)
Migrations com TypeORM
typeorm migration:generate -n NomeMigrationtypeorm migration:runemigration:revertMigrationInterfacecomup()edown()- Tabela
migrationsno banco
Migrations com Drizzle Kit
drizzle-kit generate:pg(ou mysql/sqlite)drizzle-kit migrate- Pasta
drizzle/com SQL files gerados - Sem shadow database — gera SQL puro
Workflow de CI/CD
- Migrations em pipeline: rodar antes do deploy (não no startup)
- Rollback de migration em produção (quando é seguro)
- Zero-downtime migrations: additive-only (add column nullable, backfill, add NOT NULL)
- Estratégia expand-contract para colunas renomeadas
-
Seção
## Quando usar(comparativo de abordagens):- Novo projeto TypeScript: Prisma Migrate
- NestJS + TypeORM: TypeORM CLI integrado
- Legacy Sequelize: continuar com Sequelize CLI
- Edge + Drizzle: Drizzle Kit
- Multi-banco/multi-linguagem: Flyway
-
Seção
## Armadilhas comuns(4+ armadilhas com código):synchronize: trueem produção (NUNCA — listar consequências)- Migration que adiciona coluna NOT NULL sem default em tabela com dados
- Não versionar migration files no git
- Rodar migrations no startup da aplicação (race condition em multi-instance)
- Squash de migrations em produção (sem coordenação prévia)
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre migration strategy, zero-downtime, expand-contract pattern. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: links para docs de migrations de cada ORM + artigo sobre zero-downtime migrations.
Mínimo de código: 6 snippets (migration files + comandos CLI)
Task 9: Nota 08 — Transações — gerenciamento manual vs automático
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/08 - Transações - gerenciamento manual vs automático.md
Commit: feat(node/g6): add 08 - Transações - gerenciamento manual vs automático
Frontmatter:
title: "Transações - gerenciamento manual vs automático"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- transacoes
- acid
- banco-de-dados
publish: falseConteúdo mínimo (320+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Transações garantem ACID — Atomicity, Consistency, Isolation, Durability. Em ORMs Node: Sequelize usa callbacks ousequelize.transaction(), Prisma usaprisma.$transaction()(interativa ou batch), TypeORM usaqueryRunner.startTransaction(), Drizzle usadb.transaction(). O erro mais perigoso: fazer operações parciais fora de transação em processos que devem ser atômicos. -
Seção
## O que é: ACID, quando transações são necessárias, custo de locks. -
Seção
## Como funcionacom subsecções:Níveis de isolamento
- Read Uncommitted, Read Committed, Repeatable Read, Serializable
- PostgreSQL default: Read Committed
- Quando subir o nível (e o custo)
- Fenômenos: dirty read, non-repeatable read, phantom read
Transações com Sequelize
- Managed transactions (callback):
sequelize.transaction(async (t) => { ... }) - Unmanaged transactions:
const t = await sequelize.transaction(); try { ... await t.commit() } catch { await t.rollback() } - Passar
{ transaction: t }em todas as queries dentro da transação - Savepoints
Transações com Prisma
- Interactive transactions:
prisma.$transaction(async (tx) => { ... })— tx é um Prisma Client isolado - Sequential transactions (batch):
prisma.$transaction([query1, query2])— mais rápido, sem dependências - Timeout de transação:
{ timeout: 5000 } maxWaitpara espera de connection- Prisma v6: melhorias no retry de transações
Transações com TypeORM
queryRunner:await queryRunner.startTransaction(),commitTransaction(),rollbackTransaction()@Transaction()decorator (deprecated em v0.3+)- DataSource transaction callback
Transações com Drizzle
db.transaction(async (tx) => { ... })- Nested transactions (savepoints)
- Rollback explícito com
tx.rollback()
Padrões transacionais
- Outbox pattern: persistir evento + estado na mesma transação
- Saga pattern: transações distribuídas (quando transação única não é possível)
- Pessimistic vs optimistic locking
-
Seção
## Quando usar: operações que devem ser atômicas (debitar + creditar, criar pedido + baixar estoque). -
Seção
## Armadilhas comuns(4+ armadilhas com código):- Esquecer de passar
{ transaction: t }em Sequelize (operação fora da transação) - Prisma interactive transaction com timeout muito curto
- Deadlock silencioso (detectar e resolver)
- Transação aberta muito longa bloqueando outras operações
- Fazer HTTP calls dentro de uma transação (lock mantido durante I/O)
- Esquecer de passar
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre ACID, quando usar transações, optimistic vs pessimistic locking. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: links para docs de transação de cada ORM + PostgreSQL isolation levels docs.
Mínimo de código: 8 snippets TypeScript
Task 10: Nota 09 — Paginação — offset, cursor e keyset
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/09 - Paginação - offset, cursor e keyset.md
Commit: feat(node/g6): add 09 - Paginação - offset, cursor e keyset
Frontmatter:
title: "Paginação - offset, cursor e keyset"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- paginacao
- performance
- banco-de-dados
publish: falseConteúdo mínimo (320+ linhas):
-
Callout
[!abstract] TL;DR(4+ linhas): Três estratégias de paginação com trade-offs distintos. Offset/limit: simples, mas degradação com OFFSET alto. Cursor-based: eficiente, sem duplicatas em paginação, mas sem saltar páginas. Keyset: mais eficiente ainda, usa índice, adequado para feeds infinitos. Para APIs REST modernas: cursor ou keyset. Offset só para casos de uso com “ir para página X”. -
Seção
## O que é: o problema de paginação, por que importa para performance e UX. -
Seção
## Como funcionacom subsecções:Offset/Limit
LIMIT 20 OFFSET 200— como funciona internamente no banco- Por que degrada: banco faz full scan + descarta as primeiras N linhas
- Problema de duplicatas/skips com dados mutáveis
- Quando ainda é aceitável (tabelas pequenas, admin panels, relatórios)
- Implementação em Sequelize, Prisma, TypeORM, Drizzle
Cursor-based pagination
- Opaque cursor (base64 encoded) vs transparent cursor (ID)
WHERE id > :cursor ORDER BY id LIMIT n- Implementação com Prisma (
cursor: { id: lastId }, skip: 1, take: 20) - Como retornar
nextCursorehasNextPagena resposta - Limitação: não permite pular para “página 10”
- Exemplo de response envelope:
{ data: [...], nextCursor: "...", hasNextPage: true }
Keyset pagination
WHERE (created_at, id) < (:ts, :id) ORDER BY created_at DESC, id DESC LIMIT n- Por que é mais eficiente que cursor (usa índice composto)
- Índice necessário no banco
- Implementação com Drizzle (mais natural) e Prisma (raw query)
- Caso de uso: feeds infinitos, timelines, logs
Paginação bidirecional
hasPreviousPage,startCursor,endCursor(GraphQL Relay spec)- Implementação com Prisma (
before/after)
Total count e performance
COUNT(*)é caro em tabelas grandes- Estratégia: retornar
hasMoreem vez detotalCount - Quando o total é necessário: usar
pg_estimate_count(estimativa) ou cache
-
Seção
## Quando usar: tabela de comparação offset vs cursor vs keyset por caso de uso. -
Seção
## Armadilhas comuns(4+ armadilhas com código):OFFSETalto em tabela de 10M rows (timeouts em produção)- Cursor sem índice no campo de ordenação (full scan)
- Paginação bidirecional com keyset sem índice composto
- Retornar
totalCountcomCOUNT(*)em toda requisição sem cache
-
Seção
## Em entrevista: 4+ sentenças em inglês sobre paginação strategies, quando usar cada uma, como implementar cursor-based. -
Seção
## Vocabulário PT→EN(8+ termos). -
Seção
## Fontes: links para Prisma pagination docs + artigos sobre keyset pagination.
Mínimo de código: 8 snippets (SQL + implementações nos ORMs)
Task 11: Nota 10 — Cheatsheet e decision tree de ORMs
Files:
- Create:
03-Dominios/Node/ORMs e banco de dados/10 - Cheatsheet e decision tree de ORMs.md
Commit: feat(node/g6): add 10 - Cheatsheet e decision tree de ORMs
Frontmatter:
title: "Cheatsheet e decision tree de ORMs"
created: 2026-05-10
updated: 2026-05-10
type: concept
status: seedling
progresso: andamento
tags:
- node
- orm
- cheatsheet
- banco-de-dados
publish: false
aliases:
- Decision tree ORMs
- ORM cheatsheetConteúdo mínimo (300+ linhas):
Esta nota é uma referência consolidada — priorizando densidade e escaneabilidade (tabelas, listas, snippets curtos).
-
Callout
[!abstract] TL;DR(3+ linhas): Referência rápida para entrevistas e implementação. Inclui comparativo de APIs entre os 4 ORMs, decision tree, snippets prontos para os casos mais frequentes, e checklist de produção. -
Seção
## Decision treecom lógica em cascata:Edge runtime? → Drizzle NestJS enterprise? → TypeORM ou Prisma Projeto novo TypeScript? → Prisma v6 Legacy Sequelize? → manter Sequelize (upgrade v7) SQL-first preference? → Drizzle Equipe Java/JPA background? → TypeORM Default → Prisma v6 -
Seção
## Comparativo de APIs— tabela de operações equivalentes nos 4 ORMs: | Operação | Sequelize | Prisma | TypeORM | Drizzle |- findAll / findMany / find / select
- findOne / findFirst / findOne / select().limit(1)
- create / create / save / insert
- update / update / save / update
- delete / delete / remove / delete
- eager loading (include/relations)
- transaction
-
Seção
## Snippets rápidos por ORMcom os padrões mais usados em cada ORM (copiar/colar). -
Seção
## Checklist de produção:-
synchronize: falseem TypeORM produção - Migrations versionadas no git
- Connection pool configurado (máx de conexões)
- Query logging ativo em dev, desativado em prod
- N+1 verificado com eager loading ou DataLoader
- Paginação com cursor (não offset) em tabelas grandes
- Transações em operações atômicas
- Índices nas colunas de WHERE e ORDER BY mais usadas
- Timeout de query configurado
-
-
Seção
## Vocabulário completo PT→ENcom 15+ termos consolidados do galho. -
Seção
## Em entrevista — frases prontas: Paragráfos curtos em inglês para os cenários mais perguntados:- “How do you choose an ORM?”
- “How do you handle N+1 queries?”
- “What’s your migration strategy?”
- “How do you handle transactions?”
- “How do you paginate large datasets?”
-
Seção
## Veja tambémcom wikilinks para todas as notas do galho.
Mínimo de código: 4 snippets comparativos
Task 12: Poda do tronco + atualização do índice
Files:
- Modify:
03-Dominios/JavaScript/Backend/Node.js.md - Modify:
03-Dominios/Node/index.md
Commit: chore(node/g6): prune trunk - 2 sections migrated to orms galho
Step 1: Podar seção ### ORMs do tronco
Localizar a seção ### ORMs dentro de ## How to explain in English (linhas 218-249 aproximadamente) e substituir o conteúdo completo pelo callout:
### ORMs
> [!nota] Migrado para galho próprio
>
> Os 4 ORMs principais (Sequelize, Prisma, TypeORM, Drizzle) foram expandidos em [[ORMs e banco de dados]] (galho 6). Veja em particular [[01 - Panorama de ORMs]] (comparativo), [[03 - Prisma - schema-first e type safety]] (Prisma v6), [[05 - Drizzle - ORM lightweight e type-safe]] (edge-first) e [[10 - Cheatsheet e decision tree de ORMs]] (referência rápida).Step 2: Podar seção ### N+1 queries do tronco
Localizar a seção ### N+1 queries dentro de ## Troubleshooting em produção (linhas 259-289 aproximadamente) e substituir o conteúdo completo pelo callout:
### N+1 queries
> [!nota] Migrado para galho próprio
>
> Detecção, estratégias de resolução (eager loading, DataLoader) e exemplos em todos os ORMs foram expandidos em [[ORMs e banco de dados]] (galho 6): [[06 - N+1 queries - detecção e DataLoader]].Step 3: Adicionar galho 6 no ## Veja também do tronco
Adicionar a linha após [[Observability e produção]]:
- [[ORMs e banco de dados]] — galho 6 da trilha Node Senior; os 4 ORMs (Sequelize, Prisma, TypeORM, Drizzle), N+1, migrations, transações, paginação e decision treeStep 4: Adicionar galho 6 em 03-Dominios/Node/index.md
Na seção ### Galhos da trilha Node Senior, adicionar após a linha do galho 5:
- [[ORMs e banco de dados]] — galho 6: os 4 ORMs (Sequelize, Prisma, TypeORM, Drizzle), padrões críticos (N+1, migrations, transações, paginação) e decision treeChecklist final
- Task 1: MOC criado e commitado
- Task 2: Nota 01 Panorama criada e commitada
- Task 3: Nota 02 Sequelize criada e commitada
- Task 4: Nota 03 Prisma criada e commitada
- Task 5: Nota 04 TypeORM criada e commitada
- Task 6: Nota 05 Drizzle criada e commitada
- Task 7: Nota 06 N+1 criada e commitada
- Task 8: Nota 07 Migrations criada e commitada
- Task 9: Nota 08 Transações criada e commitada
- Task 10: Nota 09 Paginação criada e commitada
- Task 11: Nota 10 Cheatsheet criada e commitada
- Task 12: Tronco podado + index atualizado e commitados