---
title: "Migraciones"
description: "Migraciones numeradas de SQL impulsadas por la CLI de Nibiru."
---

Las migraciones son archivos SQL planos en `application/settings/config/database/`, ejecutados en orden numérico. La CLI rastrea qué archivos se han ejecutado y los omite en las invocaciones posteriores.

## Nomenclatura de archivos
```
NNN-<slug>.sql
```
- `NNN`: número de tres dígitos con ceros a la izquierda para el orden de clasificación.
- `<slug>`: descripción en kebab-case (`agregar-cuenta-correo`, `crear-datos-acl`).

Ejemplo de progreso:
```
001-acl.sql
002-account.sql
003-api_registry.sql
004-timeanddate.sql
005-user.sql
006-user_to_account.sql
007-timeanddate_to_account.sql
008-user_to_acl.sql
009-account_to_api_registry.sql
010-timeanddate_to_user.sql
011-acl-data.sql
012-add-unique-key-user.sql
013-add-account-email.sql
```
## Ejecutando migraciones
```bash
./nibiru -mi local                              # APPLICATION_ENV=development
APPLICATION_ENV=staging   ./nibiru -mi staging
APPLICATION_ENV=production ./nibiru -mi production
```
El argumento `{env}` y `APPLICATION_ENV` deben coincidir. Las migraciones se dirigen a la base de datos configurada en `settings.<env>.ini` bajo `[DATABASE]`.

## ¿Qué hace el ejecutor?

Para cada archivo `*.sql` en orden numérico:

1. Busca su nombre de archivo en la tabla `_migrations`.
2. Si no está presente, abre una transacción (si el controlador admite transacciones DDL), ejecuta el archivo y inserta un registro si se realiza con éxito.
3. Si una declaración falla, revierte y sale con código distinto de cero.

La tabla `_migrations` se crea automáticamente en el primer inicio.

## SQL Idempotente

Siempre escriba migraciones que puedan volver a ejecutarse sin errores después de un fallo parcial:
```sql
CREATE TABLE IF NOT EXISTS api_registry (
    api_registry_id    INT(11) NOT NULL AUTO_INCREMENT,
    api_registry_name  VARCHAR(255) NOT NULL,
    PRIMARY KEY (api_registry_id),
    UNIQUE KEY api_registry_name_uk (api_registry_name)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
```
Para PostgreSQL:
```sql
CREATE TABLE IF NOT EXISTS api_registry (
    api_registry_id    SERIAL PRIMARY KEY,
    api_registry_name  TEXT NOT NULL UNIQUE
);
```
Para las instrucciones `ALTER`, prefiera cláusulas `IF NOT EXISTS` en motores compatibles:
```sql
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS user_email VARCHAR(255);
```
Si tu motor no soporta `IF NOT EXISTS` en la modificación, envuelve la declaración en una consulta de guardia que no haga nada cuando el cambio ya existe.

## Comandos de reinicio

:::advertencia
Los comandos de reinicio borran la tabla de auditoría de migraciones — no eliminan sus tablas de datos. Después de un reinicio, el siguiente `-mi` volverá a ejecutar *cada* migración. Asegúrate de que tu SQL sea idempotente antes de reiniciar.
:::
```bash
./nibiru -mi-reset local                       # forget all applied migrations
./nibiru -mi-reset-file 005-user.sql local     # forget a single file
```
El formulario de un solo archivo es útil cuando has corregido un error en una migración aplicada previamente y quieres volver a ejecutar solo ese archivo.

## Higiene de ramas

Dos ingenieros trabajando en ramas paralelas pueden agregar ambos `015-…` y colisionar. Convenciones que ayudan:

- **Reserva números en los títulos de pull request** antes de escribir el SQL.
- **Utiliza un espacio generoso** para hotfixes (por ejemplo, reserva `099`, `199`, `299` para cherry-picks de emergencia).
- **Prefiere migraciones adicionales** (nuevas tablas, nuevas columnas) sobre las destructivas (drops). Se fusionan más limpiamente.

## Aplanar

Para proyectos de larga duración, periódicamente colapsa las migraciones antiguas en un solo archivo semilla que represente el *esquema actual*. Mueve los originales a `archive/` para que aún exista la traza auditiva, y crea un nuevo `000-baseline-2026.sql` que cree todo de una vez. Actualiza el ejecutor de migraciones con un `INSERT INTO _migrations` manual para marcar los archivos antiguos como aplicados.

## Modelos basados en el esquema

Cuando `[GENERATOR] database = true`, los modelos se regeneran desde el esquema en vivo después de cada migración. Así que un despliegue típico es:
```bash
./nibiru -mi production
# Generator regenerates models on the next request.
./nibiru -cache-clear
```
Para implementar despliegues sin tiempo de inactividad: apague el generador (`database = false`) y realice la entrega de los modelos regenerados junto con las migraciones en las que dependen.
