Guia practica de uso de Drizzle ORM con Claude Code
Una guia practica para usar Drizzle ORM con Claude Code, con ejemplos de codigo del mundo real.
Que es Drizzle ORM
Drizzle ORM es un ORM ligero orientado a TypeScript. Su caracteristica principal es que permite escribir consultas con seguridad de tipos usando una sintaxis cercana a SQL. Combinado con Claude Code, puede construir eficientemente la capa de base de datos.
Definicion de esquema
// db/schema.ts
import {
pgTable,
text,
timestamp,
boolean,
integer,
varchar,
index,
} from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
export const users = pgTable("users", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
email: varchar("email", { length: 255 }).notNull().unique(),
name: varchar("name", { length: 100 }).notNull(),
avatar: text("avatar"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (table) => ({
emailIdx: index("email_idx").on(table.email),
}));
export const posts = pgTable("posts", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
title: varchar("title", { length: 255 }).notNull(),
content: text("content").notNull(),
published: boolean("published").default(false).notNull(),
authorId: text("author_id").notNull().references(() => users.id),
viewCount: integer("view_count").default(0).notNull(),
publishedAt: timestamp("published_at"),
createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
authorIdx: index("author_idx").on(table.authorId),
publishedIdx: index("published_idx").on(table.published, table.publishedAt),
}));
export const comments = pgTable("comments", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
content: text("content").notNull(),
authorId: text("author_id").notNull().references(() => users.id),
postId: text("post_id").notNull().references(() => posts.id, { onDelete: "cascade" }),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
Definicion de relaciones
export const usersRelations = relations(users, ({ many, one }) => ({
posts: many(posts),
comments: many(comments),
}));
export const postsRelations = relations(posts, ({ one, many }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
comments: many(comments),
}));
export const commentsRelations = relations(comments, ({ one }) => ({
author: one(users, {
fields: [comments.authorId],
references: [users.id],
}),
post: one(posts, {
fields: [comments.postId],
references: [posts.id],
}),
}));
Operaciones de consulta
import { drizzle } from "drizzle-orm/node-postgres";
import { eq, and, like, desc, sql, count } from "drizzle-orm";
import * as schema from "./schema";
const db = drizzle(pool, { schema });
// Insercion
async function createPost(data: {
title: string;
content: string;
authorId: string;
}) {
const [post] = await db
.insert(posts)
.values(data)
.returning();
return post;
}
// Busqueda (con paginacion)
async function getPosts(params: {
page?: number;
perPage?: number;
search?: string;
}) {
const { page = 1, perPage = 20, search } = params;
const conditions = [eq(posts.published, true)];
if (search) {
conditions.push(like(posts.title, `%${search}%`));
}
const [data, [{ total }]] = await Promise.all([
db
.select({
id: posts.id,
title: posts.title,
publishedAt: posts.publishedAt,
authorName: users.name,
commentCount: count(comments.id),
})
.from(posts)
.leftJoin(users, eq(posts.authorId, users.id))
.leftJoin(comments, eq(posts.id, comments.postId))
.where(and(...conditions))
.groupBy(posts.id, users.name)
.orderBy(desc(posts.publishedAt))
.limit(perPage)
.offset((page - 1) * perPage),
db
.select({ total: count() })
.from(posts)
.where(and(...conditions)),
]);
return { data, total, page, perPage };
}
// Actualizacion
async function updatePost(id: string, data: Partial<typeof posts.$inferInsert>) {
const [updated] = await db
.update(posts)
.set({ ...data, updatedAt: new Date() })
.where(eq(posts.id, id))
.returning();
return updated;
}
API de Relational Queries
// Consultas estilo Prisma
async function getPostWithRelations(id: string) {
return db.query.posts.findFirst({
where: eq(posts.id, id),
with: {
author: {
columns: { id: true, name: true, avatar: true },
},
comments: {
with: {
author: {
columns: { id: true, name: true },
},
},
orderBy: [desc(comments.createdAt)],
limit: 10,
},
},
});
}
Migraciones
// drizzle.config.ts
import type { Config } from "drizzle-kit";
export default {
schema: "./db/schema.ts",
out: "./drizzle",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL!,
},
} satisfies Config;
# Generar migracion
npx drizzle-kit generate
# Aplicar migracion
npx drizzle-kit migrate
# Iniciar Drizzle Studio (GUI)
npx drizzle-kit studio
Comparacion con Prisma
| Caracteristica | Drizzle | Prisma |
|---|---|---|
| Tamano del bundle | Ligero | Algo grande |
| Sintaxis de consultas | Cercana a SQL | API propia |
| Soporte edge | Excelente | Limitado |
| Definicion de esquema | TypeScript | DSL propio |
| Migraciones | Generacion SQL | Gestion automatica |
Uso con Claude Code
Ejemplo de como solicitar a Claude Code la implementacion con Drizzle ORM. Para comparacion con Prisma, consulte la guia completa de Prisma ORM. Para integracion con bases de datos, consulte tambien Desarrollo integrado con Supabase.
Construye la capa de base de datos con Drizzle ORM.
- Definicion de esquema para PostgreSQL
- Consultas CRUD con relaciones
- Paginacion y busqueda
- Configuracion de migraciones
Para mas detalles sobre Drizzle ORM, consulte la documentacion oficial de Drizzle ORM. Para el uso de Claude Code, consulte la documentacion oficial.
Resumen
Drizzle ORM es un ORM atractivo por su sintaxis cercana a SQL y su ligereza. Con Claude Code, puede implementar eficientemente consultas con seguridad de tipos y diseno de esquemas. Tambien es adecuado para uso en entornos edge.
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
7 plantillas de CLAUDE.md para Claude Code que puedes copiar en proyectos reales
Siete plantillas prácticas de CLAUDE.md para apps individuales, sitios de contenido, APIs, equipos y repos legacy, con errores que debes evitar.
Guia de Approval y Sandbox para Claude Code | Configuracion segura para el trabajo diario
Como dividir acciones de Claude Code en allow, ask, deny y sandbox con settings practicos, hooks y casos reales.
Guía completa para empezar con Claude Code 2026 | De cero a usarlo en tu trabajo real en 7 pasos
La guía definitiva para quienes usan Claude Code por primera vez. Desde la instalación hasta integrarlo en tu flujo de desarrollo real — con todos los tropiezos que Masa tuvo al comenzar.