docsLiquibase

Liquibase

Introducción

Liquibase es una herramienta de control de versiones para bases de datos que permite:

  • Gestionar cambios incrementales en la estructura de la base de datos
  • Mantener un historial completo de modificaciones
  • Sincronizar cambios entre diferentes entornos
  • Realizar rollbacks de manera segura
  • Trabajar con múltiples formatos (YAML, XML, JSON, SQL)

Estructura de Archivos

La estructura de archivos sigue una organización jerárquica:

src/main/resources/
├── db/
│   ├── changelog/          # Directorio principal de Liquibase
│   │   ├── changes/       # Cambios individuales
│   │   │   ├── 01-create-users-table.yaml    # Tabla de usuarios
│   │   │   ├── 02-create-roles-table.yaml    # Tabla de roles
│   │   │   └── 03-create-privileges-table.yaml # Tabla de privilegios
│   │   └── db.changelog-master.yaml  # Archivo maestro
│   └── scripts/           # Scripts SQL adicionales
│       └── initial-data.sql # Datos iniciales

Explicación de cada directorio:

  • /changelog: Contiene toda la configuración de Liquibase
  • /changes: Almacena los changesets individuales
  • /scripts: Scripts SQL para datos iniciales o migraciones complejas

Configuración Detallada

El archivo application.yml controla el comportamiento de Liquibase:

spring:
  liquibase:
    change-log: classpath:db/changelog/db.changelog-master.yaml  # Ubicación del changelog principal
    enabled: true                # Activar/desactivar Liquibase
    drop-first: false           # Si debe eliminar schema al inicio
    contexts: development       # Contexto de ejecución
    default-schema: public      # Schema por defecto
    parameters:                 # Parámetros personalizados
      table-prefix: app_        # Ejemplo de prefijo para tablas
    labels: "version-1"         # Etiquetas para filtrar changesets

Changelog Master

El archivo maestro organiza la ejecución de los cambios:

databaseChangeLog:
  # Configuración global
  - property:
      name: table.prefix
      value: app_
 
  # Precondiciones globales
  - preConditions:
      - runningAs:
          username: db_admin
 
  # Inclusión de changesets
  - include:
      file: changes/01-create-users-table.yaml
      relativeToChangelogFile: true
      context: "!prod"  # No ejecutar en producción
 
  # Más includes con configuración específica
  - include:
      file: changes/02-create-roles-table.yaml
      relativeToChangelogFile: true
      labels: "schema-setup"

Buenas Prácticas

  1. Versionado:

    • Usar prefijos numéricos en los archivos de cambios
    • Nunca modificar changelogs ya ejecutados
    • Un cambio por archivo para mejor trazabilidad
  2. Nombrado:

    • Nombres descriptivos para los archivos
    • IDs únicos para cada changeset
    • Incluir el autor en cada changeset
  3. Organización:

    • Separar cambios estructurales de datos
    • Mantener un changelog master limpio
    • Agrupar cambios relacionados
  4. Rollback:

    • Incluir siempre secciones de rollback
    • Probar los rollbacks antes de desplegar
    • Documentar cambios que no son reversibles

Comandos Avanzados

# Comandos básicos
./mvnw liquibase:update               # Actualizar BD
./mvnw liquibase:rollback            # Rollback
./mvnw liquibase:status             # Ver estado
 
# Comandos avanzados
./mvnw liquibase:diff               # Comparar esquemas
./mvnw liquibase:generateChangeLog  # Generar changelog
./mvnw liquibase:clearCheckSums    # Limpiar checksums
 
# Opciones específicas
./mvnw liquibase:update -Dliquibase.contexts=test    # Contexto específico
./mvnw liquibase:rollback -Dliquibase.rollbackTag=v1.0  # Rollback a tag

Integración con Spring Boot

Configuración Avanzada

spring:
  liquibase:
    enabled: true
    drop-first: false
    change-log: classpath:db/changelog/db.changelog-master.yaml
    contexts: development
    default-schema: public
    parameters:
      app.name: myapp
      app.version: 1.0.0
    labels: "version-1,schema-update"
    rollback-file: rollback-script.sql
    test-rollback: true
    database-change-log-lock-table: DATABASECHANGELOGLOCK
    database-change-log-table: DATABASECHANGELOG

Eventos del Ciclo de Vida

@Component
public class LiquibaseCustomizer {
    @EventListener
    public void onLiquibaseStart(LiquibaseStartEvent event) {
        // Personalización antes de la ejecución
    }
 
    @EventListener
    public void onLiquibaseEnd(LiquibaseEndEvent event) {
        // Limpieza después de la ejecución
    }
}