Revisão de Código para SQL
Evidências de EXPLAIN e notas de rollback são necessárias para pull requests de PostgreSQL 18.4 - checklist do revisor para migrações, queries ORM e SQL ad hoc em repositórios de aplicação.
Busque em todas as páginas da documentação
Evidências de EXPLAIN e notas de rollback são necessárias para pull requests de PostgreSQL 18.4 - checklist do revisor para migrações, queries ORM e SQL ad hoc em repositórios de aplicação.
## Checklist de Revisão de PR SQL (copiar no comentário da revisão)
### Migrações
- [ ] Versão única; nome do arquivo tem ID do ticket
- [ ] Risco de lock: baixo / médio / alto (Skill de Segurança de Migração)
- [ ] CONCURRENTLY para índice de produção em tabelas grandes
- [ ] SQL de Rollback em db/rollback/ ou corpo do PR
- [ ] Ordem de deploy: migração antes da aplicação
### Queries
- [ ] EXPLAIN (ANALYZE, BUFFERS) de staging anexado
- [ ] Sem regressão de seq scan em tabelas grandes
- [ ] Queries parametrizadas ($1 / binds nomeados)
- [ ] LIMIT em endpoints de lista
### Segurança
- [ ] Privilégio mínimo da role (não superusuário)
- [ ] search_path definido ou nomes com schema qualificado
- [ ] Políticas RLS se tabela de tenantQuando usar isso:
db/migrations/, *.sql, arquivos de query do repositórioPR: Adicionar método de repositório findOpenOrdersByTenant.
Autor fornece:
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, total, created_at
FROM orders
WHERE tenant_id = $1 AND status = 'open'
ORDER BY created_at DESC
LIMIT 100;Index Scan using idx_orders_tenant_status on orders
Buffers: shared hit=120 read=4
Execution Time: 1.2 msRevisor aprova - índice existe, LIMIT presente, buffers razoáveis.
Exemplo de PR ruim (rejeitar):
SELECT * FROM orders WHERE tenant_id = $1 OR tenant_id = $2;
-- Sem EXPLAIN, sem LIMIT, OR impede índice em alguns planejadoresModelo de comentário do revisor:
Solicitar alterações:
1. Anexar EXPLAIN (ANALYZE, BUFFERS) de staging
2. Substituir OR por padrão IN (...) ou UNION ALL
3. Listar colunas explicitamente; remover SELECT *
4. Ver Skill de Revisão EXPLAIN para rubrica de aprovação/falha| Sinal | Aprovar | Solicitar alterações |
|---|---|---|
CREATE INDEX em tabela grande | CONCURRENTLY em arquivo separado | Índice em transação única |
NOT NULL nova coluna | expand-contract ou caminho rápido de default do PG documentado | Risco de reescrita de tabela não explicado |
| Adicionar FK | NOT VALID + VALIDATE dividido | Validação inline em tabela enorme |
| Backfill de dados | UPDATE em batch com commit | Uma transação enorme |
# RUIM: N+1
for order in orders:
items = session.query(Item).filter_by(order_id=order.id).all()
# BOM: evidência de joinedload no PR
orders = session.query(Order).options(joinedload(Order.items)).filter(...)-- rollback/V20260709_128__orders_priority_down.sql
DROP INDEX CONCURRENTLY IF EXISTS idx_orders_priority;
ALTER TABLE orders DROP COLUMN IF EXISTS priority;SET search_path = pg_catalog, app.pg_indexes no PR.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Sessão de pareamento | Primeiro PR SQL de júnior | Migração trivial rotineira |
| sqlfluff/sql-lint automatizado | Estilo e anti-padrões óbvios | Julgamento de EXPLAIN |
| Horário de atendimento de DBA | Equipe de alto volume | Bloquear pequenas correções |
Se a forma da query não mudou e não é um caminho crítico, anote a isenção. Qualquer alteração de filtro/join/índice em tabela grande requer EXPLAIN.
Pelo menos um DBA ou engenheiro sênior da lista de rotação. Regra de duas pessoas para produção se aplica.
Sim para PII e volume similar ao de produção. Seeds de desenvolvimento ainda não devem usar padrões de superusuário que a produção proíbe.
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 e stacks de aplicação usando migrações Flyway 10+.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026