O que é um ORM? Como as apps falam com as bases de dados, explicado
Um ORM (mapeador objeto-relacional) é uma biblioteca de código que fica entre uma app e uma base de dados relacional. Em vez de escrever consultas de base de dados em SQL, os programadores trabalham com os dados como objetos normais na sua linguagem de programação — db.booking.create(...) ou Booking.find(...) — e o ORM traduz isso para SQL, executa-o e transforma os resultados de novo em objetos. Exemplos populares são Prisma e Drizzle para TypeScript, SQLAlchemy para Python e Entity Framework Core para C#.
Porque é que os ORM importam quando cria com IA
Quando um criador de apps com IA acrescenta uma base de dados à sua app, normalmente acrescenta também um ORM para falar com ela. Não vai precisar de escrever código de ORM, mas convém saber que ele existe:
- O seu modelo de dados vive no código. O ficheiro de esquema do ORM é muitas vezes a descrição mais clara dos dados da sua app: que tabelas existem, que campos tem cada uma e como se ligam. Lê-lo é uma forma rápida de confirmar que a IA percebeu a sua app.
- As alterações à base de dados passam por migrações. Quando pede «acrescenta um número de telefone aos clientes», a IA atualiza o modelo e cria uma migração. Saber isto ajuda a perceber porque é que uma alteração pode ter de ser aplicada antes de funcionar em produção.
- Segurança por defeito. Os ORM constroem as consultas de forma a proteger contra injeção de SQL, uma das falhas de segurança mais comuns em apps que montam consultas à mão.
- Armadilhas de desempenho. Os ORM facilitam executar, sem querer, centenas de pequenas consultas quando bastava uma. É uma causa frequente de páginas lentas em apps criadas com IA.
Uma analogia do dia a dia
Imagine um viajante britânico e um lojista japonês que não partilham uma língua e comunicam através de um intérprete.
O viajante (a sua app) diz: «Queria os três chás mais baratos que tiver.» O intérprete (o ORM) traduz isso para japonês preciso (SQL), entrega ao lojista (a base de dados) e traduz a resposta de volta para inglês.
O viajante nunca aprende japonês, e para a maioria das conversas isso não faz mal. Mas numa negociação complicada pode ajudar falar diretamente — e é por isso que a maioria dos ORM deixa os programadores escrever SQL puro quando é preciso.
Como funciona um ORM
Bases de dados como o Postgres guardam dados em tabelas de linhas e colunas e são consultadas em SQL. As linguagens de programação trabalham com objetos: uma marcação com uma data, um cliente e um estado. O ORM faz a correspondência entre um e outro:
| Lado da base de dados | Lado do ORM / código |
|---|---|
Tabela bookings | Modelo Booking |
| Linha | Um objeto de marcação |
Coluna starts_at | Campo startsAt |
Chave estrangeira customer_id | Relação booking.customer |
SELECT, INSERT, UPDATE, DELETE | Métodos find, create, update, delete |
Estas quatro operações são as ações CRUD em que quase todas as apps assentam.
Um exemplo prático: marcações com Prisma
Eis um esquema Prisma simplificado para uma app de marcações de um salão de cabeleireiro. Descreve duas tabelas e a forma como estão ligadas:
model Customer {
id Int @id @default(autoincrement())
name String
email String @unique
bookings Booking[]
}
model Booking {
id Int @id @default(autoincrement())
startsAt DateTime
service String
customer Customer @relation(fields: [customerId], references: [id])
customerId Int
}
Dito por palavras simples: um cliente tem um nome, um email único e várias marcações; cada marcação tem uma hora de início, um serviço e pertence a um único cliente.
Agora a app quer «as próximas marcações da Lena, pela ordem mais próxima»:
const bookings = await db.booking.findMany({
where: {
customer: { email: "lena@example.com" },
startsAt: { gte: new Date() },
},
orderBy: { startsAt: "asc" },
});
O ORM transforma isto em SQL mais ou menos assim, executa-o e devolve uma lista de objetos de marcação:
SELECT b.* FROM "Booking" b
JOIN "Customer" c ON c.id = b."customerId"
WHERE c.email = $1 AND b."startsAt" >= $2
ORDER BY b."startsAt" ASC;
Os $1 e $2 são marcadores: o email e a data são enviados separadamente do texto da consulta, e é isso que evita a injeção de SQL.
Migrações
Se depois pedir «deixa os clientes acrescentar um número de telefone», a IA acrescenta phone String? ao modelo Customer (o ? significa opcional) e gera uma migração — um pequeno script SQL como ALTER TABLE "Customer" ADD COLUMN "phone" TEXT;. As migrações são guardadas por ordem, para que qualquer cópia da base de dados possa ser levada à mesma estrutura, e o histórico de alterações fica registado.
ORM comuns por linguagem
| Linguagem | ORM comuns |
|---|---|
| TypeScript / JavaScript | Prisma, Drizzle, TypeORM, Sequelize |
| Python | SQLAlchemy, ORM do Django, SQLModel |
| C# | Entity Framework Core |
| Java | Hibernate (muitas vezes através do Spring Data JPA) |
| Ruby | Active Record |
Os ORM variam na quantidade de SQL que escondem. O Prisma usa a sua própria linguagem de esquema e estilo de consulta; o Drizzle mantém-se deliberadamente próximo da forma do SQL, mantendo tudo tipado. Ferramentas mais leves, chamadas construtores de consultas, como o Knex ou o Kysely para TypeScript, ajudam a construir SQL no código sem mapear as linhas para objetos completos.
Termos-chave
| Termo | Significado |
|---|---|
| Modelo | A definição, no código, de uma tabela e dos seus campos. |
| Esquema | A descrição completa de todas as tabelas, campos e relações. |
| Relação | Uma ligação entre modelos, como uma marcação que pertence a um cliente. |
| Migração | Um script versionado que altera a estrutura da base de dados. |
| Construtor de consultas | Uma ferramenta mais leve para construir SQL no código, sem o mapeamento completo para objetos. |
| Problema N+1 | Executar uma consulta para uma lista e depois mais uma para cada item — lento à escala. |
| SQL puro | SQL escrito à mão, usado quando o ORM atrapalha. |
Ideias erradas comuns
- «Um ORM é uma base de dados.» Não é. É um tradutor. Continua a precisar de uma base de dados, como o Postgres.
- «Com um ORM não é preciso perceber os seus dados.» Tabelas mal desenhadas são igualmente penosas através de um ORM. Um bom modelo de dados importa mais do que a ferramenta.
- «Os ORM são sempre lentos.» As consultas do dia a dia são sem problema. A lentidão costuma vir de padrões como consultas N+1 ou índices em falta, que se podem corrigir.
- «ORM significa que nunca há risco de injeção de SQL.» Os métodos padrão do ORM são seguros, mas SQL puro escrito com dados do utilizador colados diretamente continua a ser perigoso.
- «Editar o ficheiro de esquema altera a base de dados em produção.» Só depois de criar uma migração e de a aplicar a essa base de dados.
O que pedir ao seu criador com IA
- «Mostra-me o esquema da base de dados e explica cada tabela e relação em linguagem simples.»
- «Que ORM usa este projeto, e onde estão as migrações?»
- «Antes de alterares qualquer tabela, diz-me se os dados existentes vão ser afetados, e nunca apagues uma coluna que tenha dados sem me perguntares.»
- «Verifica as páginas mais lentas à procura de consultas N+1 e acrescenta índices onde as listas são filtradas ou ordenadas.»
- «Garante que toda a consulta que usa dados do utilizador passa pelo ORM ou usa parâmetros — nada de SQL montado com texto.»
ORM no Mythex
Quando a sua app precisa de guardar dados, o Mythex acrescenta uma base de dados Postgres dedicada ao projeto — peça-o no chat ou use o comando /database — e injeta os respetivos detalhes de ligação no espaço de trabalho e na app publicada (Base de dados). Depois, o agente escreve o código que lê e guarda os seus dados. Se tiver uma preferência — «usa o Prisma», «usa o SQLAlchemy» ou «SQL puro, sem ORM» — diga-o no chat. Peça-lhe que explique o esquema sempre que quiser verificar a estrutura; pode ler os ficheiros no editor de código. Para a visão geral, veja o que é uma base de dados e SQL vs NoSQL.
Perguntas
O que é um ORM, em termos simples?
Um ORM (mapeador objeto-relacional) é uma biblioteca de código que fica entre a sua app e uma base de dados relacional. Permite que os programadores leiam e guardem dados como objetos normais na sua linguagem de programação, e escreve as consultas SQL por trás da cena.
Quais são alguns exemplos de ORM?
Os ORM mais comuns incluem Prisma e Drizzle para TypeScript e JavaScript, SQLAlchemy e o ORM do Django para Python, Entity Framework Core para C#, Hibernate para Java e Active Record em Ruby on Rails.
Um ORM é melhor do que escrever SQL?
Depende da tarefa. Um ORM torna as leituras e escritas do dia a dia mais rápidas de escrever, mais seguras e mais fáceis de alterar, enquanto o SQL escrito à mão dá controlo total para relatórios complexos ou consultas críticas para o desempenho. A maioria dos ORM permite recorrer a SQL puro quando for preciso.
O que é uma migração?
Uma migração é um pequeno script versionado que altera a estrutura da base de dados, por exemplo para acrescentar uma tabela ou uma coluna. Os ORM conseguem gerar migrações a partir do modelo de dados, para que todas as cópias da base de dados — no portátil, nos testes e em produção — fiquem com a mesma estrutura.