Liquibase es una librería (Java) de base de datos de código abierto para rastrear, administrar y aplicar cambios en el Modelo de base de datos desde línea de comandos y se puede integrar muy fácilmente con Maven y Spring (Liquibase no está restringida solo a Java). Se inició en 2006 para permitir un seguimiento más fácil de los cambios en las bases de datos, especialmente en un entorno de desarrollo de software ágil.
Es realmente muy interesante la facilidad con que se integra, por ejemplo, con el framework Spring. Ya que por ejemplo, una de las aplicaciones reales que nos permitirá realizar será la automatización del proceso de cambios en los modelos de las bases de datos afectadas, con lo que nos va a permitir abandonar la ejecución de scripts para realizar los cambios como ese maldito orden con el que se tenían que ir ejecutando. También, los miembros del equipo de desarrollo van a tener al alcance la información sobre que cambios se han ído realizado y quien los ha realizado (control).
Por ahora, Liquibase soporta bases de datos como: MySQL, PostgreSQL, Oracle, etc… podéis ver en este enlace todas las BDs soportadas.
Uno de los mayores logros de Liquibase es la integración con herramientas de CI/CD como: Jenkins o Travis CI, etc.. como también herramientas de Project management como: Rake o Grunt, etc… Solo se requiere Java 1.6+ para poder ejecutarse.
La base de Liquibase es muy simple, ya que se basa en ficheros XML o JSON o YAML que, mediante una syntax, tendrán definidos nuestros esquemas de datos y los changesets que siguen desde la creación inicial.
De esta forma, podremos ir actualizando, por ejemplo, nuestro “Código fuente de la aplicación”, el “Modelo de la base de datos” o la “Infraestructura” pudiendo utilizar, por ejemplo en AWS “CloudFormation” o los “Resource Manager Templates” en Azure. Definiremos un fichero changeset master, donde Liquibase realizará las acciones necesarias para actualizar la base de datos. Todos los cambios que se vayan realizando, Liquibase, creará una tabla llamada “databasechangelog” dentro de nuestro modelo que mantendrá el registro de todos los changesets futuros y, finalmente, creará una segunda tabla llamada “databasechangeloglock” para poder prevenir aquellos cambios que se puedan realizar en paralelo.
Realmente una de sus magnifidades es el poder abandonar esa “maldita” creación de scripts sql incrementales (sin perder la paciencia y cargarnos, naturalmente, la cultura DevOps). Por lo tanto teníamos situaciones como eran la programación de scripts de creación de tablas, índices o la própia inserción de datos, etc… y poco a poco se podía ir “avanzando” en desarrollo (tanto de la aplicación como del modelo de datos). Todos los miembros del equipo de desarrollo estaban creando esos scripts con las modificaciones oportunas que exigía el backlog que llevaban a cabo. En definitiva, teníamos un proceso totalmente manual y peligroso, que podía llevarnos a confusiones, sobre todo en el momento que perdíamos, por decirlo así, el orden de la ejecución de los mismos o cuantos podían faltar pa su ejecución.
Haremos, entonces, un listado de “Tags” que nos permite introducir Liquibase y así poder ir construyendo nuestro conjunto de cambios en la base de datos:
<databaseChangeLog>
, será el primer tag para que Liquibase pueda empezar a trabajar con cada uno de los cambios.<preConditions>
, en caso que existan condiciones previas.<changeSet>
, mediante esta etiqueta se definen cad auno de los cambios, por ejemplo podremos definir:<createTable>
, para crear tablas.<dropTable>
, eliminar tablas.<addColumn>
, añadir columnas.<renameColumn>
, renombrar columnas.<modifyColumn>
, modificar columnas.<dropColumn>
. eliminar columnas.<sqlFile>
, ejecución de scripts dentro del própio Liquibase.
<include>
, podremos particionar el propio fichero master e ir ejecutando varios ficheros changeset.<includeAll>
, lo mismo que la anterior pero para agrupar múltiples ficheros sin necesidad de listarlos.<context>
, nos permitirá distinguir entre los distintos entornos (desarrollo, preproducción y producción por ejemplo).
También, con Liquibase, tendremos a nuestro alcance otras funcionales del tipo:
- Update, para poder realizar cambios en ejecuciones anteriores de nuestro fichero changeset.
- Rollback, para deshacer aquellos cambios ya ejecutados.
- Diff, para buscar cambios que se puedan haber realizado, por ejemplo, algunas posibilidades:
- Diferencias entre versiones.
- Ausencias de: tablas, vistas, columnas, índices, claves primarias, etc…
- DBDoc, para generar Documentación de todo el histórico de ejecuciones y la evolución del Modelo.
- SQL Output, en caso que no queramos ejecutar, por ejemplo los Rollback, mediante Liquibase. Nos dará un fichero .sql que podremos ejecutar manualmente.
Algunos ejemplos de fichero en formato JSON pueden ser:
Create Table:
{
"changeSet": {
"id": "createTable-example",
"author": "liquibase-docs",
"changes": [
{
"createTable": {
"catalogName": "cat",
"columns": [
{
"column": {
"name": "address",
"type": "varchar(255)"
}
}]
,
"remarks": "A String",
"schemaName": "public",
"tableName": "person",
"tablespace": "A String"
}
}]
}
}
Alter Table:
{
"changeSet": {
"id": "addLookupTable-example",
"author": "liquibase-docs",
"changes": [
{
"addLookupTable": {
"constraintName": "fk_address_state",
"existingColumnName": "state",
"existingTableName": "address",
"newColumnDataType": "char(2)",
"newColumnName": "abbreviation",
"newTableName": "state"
}
}]
}
}
Realmente es muy interesante poder aplicar un control de versiones a nuestros modelos de datos ya que, no lo olvidemos, están en constante cambio y son la parte más crítica de nuestro producto. Una indisponibilidad podría ser nuestro fin.
Autor: Joakim Vivas