Back

Desarrollo de Bases de Datos Schema-First con Drizzle

Desarrollo de Bases de Datos Schema-First con Drizzle

Tus tipos de TypeScript dicen una cosa. Tu base de datos dice otra. Las consultas fallan en tiempo de ejecución y te quedas depurando desajustes que nunca deberían haber existido.

El diseño de bases de datos schema-first con Drizzle resuelve esto al hacer de tu código TypeScript la única fuente de verdad. Tus definiciones de esquema impulsan tanto los tipos de tu aplicación como la estructura de tu base de datos, eliminando la desconexión que causa sorpresas en tiempo de ejecución.

Este artículo explica cómo funciona el desarrollo schema-first con Drizzle ORM, cuándo usar diferentes flujos de trabajo de migración y los errores comunes que debes evitar.

Puntos Clave

  • Drizzle ORM sigue un enfoque code-first donde las definiciones de esquema en TypeScript sirven como la única fuente de verdad para tipos, consultas y estructura de base de datos.
  • Drizzle Kit ofrece dos rutas de migración: push para iteración local rápida y generate/migrate para despliegues auditables y seguros para equipos.
  • Para proyectos brownfield con bases de datos existentes, usa drizzle-kit pull para introspeccionar tu esquema antes de generar migraciones y evitar recrear tablas.
  • Los desajustes en nombres de restricciones entre el nombrado determinístico de Drizzle y las bases de datos creadas manualmente pueden desencadenar declaraciones de migración inesperadas.

Qué Significa Realmente Schema-First en Drizzle

Drizzle es fundamentalmente code-first. Defines tablas, columnas y relaciones en TypeScript, y esa definición se convierte en autoritativa para todo lo que viene después: consultas, migraciones e inferencia de tipos.

import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core"

export const posts = pgTable("posts", {
  id: serial().primaryKey(),
  title: text().notNull(),
  content: text(),
  createdAt: timestamp().defaultNow(),
})

Este archivo de esquema cumple un doble propósito. Drizzle ORM lo usa para consultas con tipado seguro. Drizzle Kit lo usa para generar o aplicar cambios en la base de datos.

El término “schema-first” aquí significa que tus definiciones de TypeScript lideran. La base de datos sigue.

Code-First vs Database-First: Entendiendo la Distinción

Los flujos de trabajo tradicionales database-first tratan la base de datos como autoritativa. Creas tablas manualmente o con scripts SQL, luego generas código de aplicación a partir de la estructura existente.

Las comparaciones entre code-first y database-first a menudo confunden estos términos. En el contexto de Drizzle:

  • Code-first: Tu esquema TypeScript impulsa los cambios en la base de datos
  • Database-first: Extraes la estructura de base de datos existente a TypeScript usando drizzle-kit pull

Drizzle soporta ambos. Para proyectos greenfield, code-first es típicamente más limpio. Para escenarios brownfield—unirte a un proyecto con una base de datos existente—la introspección vía pull te permite comenzar rápidamente.

El Flujo de Trabajo de Drizzle Kit: Push vs Generate

Drizzle Kit ofrece dos rutas principales para aplicar cambios de esquema a tu base de datos.

Schema Push para Iteración Rápida

npx drizzle-kit push

Push compara tu esquema con la base de datos y aplica cambios directamente. Sin archivos de migración. Sin paso de revisión.

Esto funciona bien para:

  • Proyectos individuales
  • Prototipado temprano
  • Bases de datos de desarrollo local que puedes recrear

El compromiso es la visibilidad. No tendrás un registro de qué cambió o cuándo.

Migraciones Generadas para Seguridad del Equipo

npx drizzle-kit generate
npx drizzle-kit migrate

generate crea archivos de migración SQL. migrate los aplica. Los archivos viven en control de versiones, creando una pista de auditoría.

Este enfoque se adapta a:

  • Entornos de equipo donde los cambios necesitan revisión
  • Despliegues en producción que requieren capacidad de rollback
  • Escenarios de cumplimiento que necesitan documentación de cambios

Ningún método es universalmente correcto. El flujo de trabajo de Drizzle Kit acomoda ambos según tu contexto.

Configurando Drizzle Kit

Tu drizzle.config.ts le indica a Drizzle Kit dónde encontrar esquemas y almacenar migraciones:

import { defineConfig } from "drizzle-kit"

export default defineConfig({
  dialect: "postgresql",
  schema: "./src/db/schema.ts",
  out: "./drizzle/migrations",
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
})

Drizzle soporta las principales bases de datos SQL incluyendo PostgreSQL, MySQL y SQLite/libSQL, con dialectos adicionales como MSSQL y CockroachDB emergiendo. La configuración permanece en gran medida consistente entre bases de datos—solo cambian el dialecto y las opciones específicas del driver.

Errores Comunes a Evitar

El desarrollo schema-first con Drizzle no está exento de puntos de fricción.

Las tablas existentes requieren manejo cuidadoso. Si estás adoptando Drizzle en una base de datos con tablas existentes, tu primer generate puede producir migraciones que intenten recrear todo. Usa pull primero para sincronizar tu archivo de esquema con la realidad.

La introspección puede producir diferencias ruidosas. Extraer de una base de datos puede incluir nombres de restricciones o valores predeterminados que difieren de lo que escribirías manualmente. Los generates subsiguientes pueden marcar estos como cambios incluso cuando nada significativo cambió.

Los desajustes en nombres de restricciones causan migraciones inesperadas. Drizzle genera nombres de restricciones de forma determinística. Si tu base de datos tiene nombres diferentes (de creación manual u otra herramienta), verás declaraciones ALTER que renombran restricciones sin cambiar el comportamiento.

Las migraciones en tiempo de ejecución necesitan manejo de errores. Si estás aplicando migraciones programáticamente durante el despliegue, envuélvelas en un manejo de errores adecuado. Una migración fallida a mitad de despliegue puede dejar tu base de datos en un estado inconsistente.

Cuándo Schema-First Mejora Tu Flujo de Trabajo

El desarrollo schema-first con Drizzle ORM brilla cuando:

  • Quieres garantías en tiempo de compilación de que las consultas coinciden con tu esquema
  • Múltiples desarrolladores necesitan coordinar cambios en la base de datos
  • Estás desplegando en entornos edge o serverless donde el tamaño del bundle importa
  • Prefieres sintaxis similar a SQL sobre query builders abstractos

Drizzle Studio complementa este flujo de trabajo con una interfaz visual para explorar datos y probar consultas contra tu esquema.

Conclusión

Comienza con tu archivo de esquema. Define tablas que coincidan con tu dominio. Usa push mientras iteras localmente, luego cambia a generate y migrate antes de involucrar a compañeros de equipo o desplegar a producción.

El objetivo no es elegir un flujo de trabajo para siempre—es entender los compromisos para que elijas la herramienta correcta para cada fase del desarrollo.

Preguntas Frecuentes

Sí. Ejecuta drizzle-kit pull para introspeccionar tu base de datos existente y generar un esquema TypeScript coincidente. Esto evita migraciones destructivas. Una vez que tu archivo de esquema refleje el estado actual de la base de datos, puedes comenzar a usar generate y migrate para todos los cambios futuros sin arriesgar pérdida de datos.

Cambia a generate una vez que tu proyecto vaya más allá del prototipado individual. Tan pronto como otros desarrolladores estén involucrados o estés desplegando a staging o producción, los archivos de migración proporcionan la pista de auditoría y el proceso de revisión que necesitas. Push es mejor reservado para desarrollo local donde la base de datos puede ser recreada de forma segura.

Sí. Drizzle soporta definir claves foráneas directamente en tu esquema y proporciona una API de relaciones para declarar relaciones uno-a-uno, uno-a-muchos y muchos-a-muchos. Estas relaciones potencian la API de consultas relacionales, que te permite obtener datos anidados de forma type-safe sin escribir joins SQL crudos.

Ambos son ORMs code-first, pero difieren en filosofía. Prisma usa su propio lenguaje de esquema y genera un cliente a partir de él. Drizzle define esquemas en TypeScript plano, dándote control directo sobre la salida SQL y tamaños de bundle más pequeños. Drizzle está más cerca de SQL por diseño, mientras que Prisma abstrae más de ello.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay