Con la mentalidad DevOps se incluye la necesidad de la automatización. Es decir, la necesidad de eliminar la intervención manual (y con ella el error humano) de la ecuación tanto como sea posible en el proceso de implantación. Por lo que sabemos, los errores son mucho más probables cuando una tarea tiene que ser ejecutada por otro que no sea una máquina. La base de datos es una parte tan grande de este proceso como otros elementos y suele ser relegada al final de las tareas de implantación. O, puede también existir el miedo de que una aplicación no sea capaz de manejar los detalles tan bien como una persona y que pueda resultar en una pérdida de datos si no se tiene cuidado en hacer las cosas bien.

No obstante, esto no debería ser así. No se debería necesitar a nadie para actualizar un modelo a la última versión de una aplicación, o a la inversa, para revertir cambios. El aumento en velocidad y fiabilidad, sin la supervisión de nadie, es lo que permite ejecutar una implantación continua. Otro valor añadido es que las actualizaciones de modelo pueden ser testadas antes de ponerlas en producción.

Así, os presento:

Las herramientas para ejecutar actualizaciones de modelo automáticas suelen ser conocidas como de “migración de base de datos”. Existen muchas ahí fuera, y me gustaría hablar de una que he usado en algunos proyectos. Esto no significa que CAPSiDE apoye o recomiende Liquibase. Echa un vistazo a las herramientas que tu ORM lleva (muchas de ellas ya cuentan con herramientas de migración de modelo).

Vamos con Liquibase:

Es una herramienta para mantener el modelo de base de datos y su evolución bajo control de origen aportando un XML (o JSON o YAML) DSL que define dicho esquema y los changesets que siguen la creación inicial. De esta forma, un proyecto puede mantenerse sincronizado:

¿Cómo funciona?

Liquibase es una aplicación Java que puede integrarse en proyectos Maven/Graddle/Ant o ejecutarse independientemente en la línea de comandos. También puede integrarse en aplicaciones Java EE/Spring para ejecutar cambios sobre la implantación de la app, pero Liquibase no está restringida a Java, y es agnóstica en cuanto a bases de datos (pincha aquí para ver una lista de bases de datos soportadas). Aparte de que se puede ejecutar en la línea de comandos, también puede integrarse en cualquier build o herramienta de Project management (Rake, Grunt, Module::Build, etc) y cualquier server CI (Jenkins, Travis CI, Team Foundation Server) que estés utilizando para tu proyecto. Solo se requiere Java 1.6 + para ejecutar Liquibase.

Para saber qué hacer, son necesarios los archivos changesets, que describen el modelo de tu base de datos. Un DSL de Liquibase ofrece las herramientas para hacerlo. Otro ejemplo ayudará a ver cómo es un archivo changeset:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <preConditions>
        <runningAs username="liquibase"/>
    </preConditions>

    <changeSet id="1" author="nvoxland">
        <createTable tableName="person">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="firstname" type="varchar(50)"/>
            <column name="lastname" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="state" type="char(2)"/>
        </createTable>
    </changeSet>

    <changeSet id="2" author="nvoxland">
        <addColumn tableName="person">
            <column name="username" type="varchar(8)"/>
        </addColumn>
    </changeSet>
    <changeSet id="3" author="nvoxland">
        <addLookupTable existingTableName="person" existingColumnName="state" newTableName="state" newColumnName="id" newColumnDataType="char(2)"/>
    </changeSet>

</databaseChangeLog>

Si este extracto te hace temblar de pensar en la verborrea del XML, existe una versión YAML.

Desde un archivo changeset master, Liquibase hará las acciones necesarias para actualizar la base de datos. Para saber qué cambios aplicar, la aplicación creará una tabla (databasechangelog) en el modelo que mantendrá un registro de cualquier changesets que se le aplique en cualquier fecha. También creará otra tabla (databasechangeloglock) para prevenir cambios en paralelo de dos comandos Liquibase.

El comando update no es el único que ofrece Liquibase. Muchos tipos de comandos ayudan a gestionar la base de datos, extraer información, revertir cambios, generar SQL, junto a otros.

Por ejemplo, ejecutando el siguiente comando:

liquibase \
      --driver=oracle.jdbc.OracleDriver \
      --classpath=\path\to\classes:jdbcdriver.jar \
      --changeLogFile=db.master_changelog.xml \
      --url="jdbc:oracle:thin:@localhost:1521:oracle" \
      --username=scott \
      --password=tiger \
      update

Asumiendo que el db.master_changelog.xml fuera el xml previo, crearía una tabla de “person”, luego le añadiría una columna “username” a dicha tabla, y después crearía una tabla de búsqueda para “person” (no hay solo operaciones básicas SQL, sino que con plugins podemos extender Liquibase para que nos proporcione un SQL más complejo asociado con operaciones Liquibase)

Además, cualquier opción de un comando Liquibase puede ir a un archivo de propiedades así que no es necesario tener que escribir cada parámetro cada vez.

Si en la base de datos objetivo ya se han ejecutado dichas operaciones previamente, Liquibase lo reconocerá y no las ejecutará.

En el caso de que te estés preguntando si puedes utilizar Liquibase en tu base de datos preexistente, puedes utilizar el comando generateChangeLog para crear un changeset inicial.

¿Qué me proporciona Liquibase?

Todo esto parece genial, pero… ¿qué me aporta realmente esta herramienta aparte que no le dé SQL al departamento de operaciones?

Lo primero de todo, el DSL. Ya sea con XML, YAML o JSON (o incluso con un pseudoSQL), te proporciona cuatro importantes cosas:

De la última ventaja viene una de las mejores características de Liquibase:  etiquetado. El mismo concepto que una etiqueta VCS. Marcas un punto como ancla al que volver más tarde si es necesario. La finalidad principal de las etiquetas es volver hacia ellas más tarde. Para hacerlo, revertirá todos los changesets que hubieran venido después de la etiqueta.

Es importante que para cada changeset haya operaciones de reversión definidas. Si has utilizado el DSL de Liquibase las tendrás automáticamente ya creadas. Si no, todavía puedes definirlas en la sección reversión de un changeset. Como esto:

- changeSet:
      id: changeRollback
      author: nvoxland
      changes:
        - createTable:
            tableName: changeRollback1
            column:
              - column:
                  name: id
                  type: int
      rollback:
        - dropTable:
            tableName: changeRollback1

Si sincronizas tus etiquetas de aplicación con las etiquetas de Liquibase, obtendrás una forma muy sencilla de hacer una transición entre una base de datos hacia otra.

Otra buena característica que tiene Liquibase es independencia entre el proyecto y el stack tecnológico. No necesitas depender de un lenguaje en particular, lo que significa que el manejo de base de datos puede unificarse entre proyectos, simplificando las operaciones día a día.

Esto no puede ser fácil, ¿verdad?

No lo es. Existen algunos escollos al utilizar Liquibase y algunas dificultades que deben superarse para poder utilizar esta herramienta al máximo.

Lo primero de todo, con un auténtico espíritu DevOps, Liquibase no se puede utilizar si tanto los devs como los ops no la compran. El equipo de desarrollo necesita una fuerte disciplina ya que cada cambio debe ser registrado en un changeset con su reversión. No es tan importante durante el desarrollo y antes de que la primera versión se libere para producción, ya que el modelo puede ser recreado en cualquier momento, pero después equivocarse poniendo cualquier cambio dentro de un changeset y después etiquetarlo para cada liberación de código causará problemas y entonces Liquibase servirá de más bien poco.

Para el equipo de operaciones es más sencilla la entrada, ya que facilita la gestión de las bases de datos ofreciendo una forma automatizada de utilizarla, sin su inervención. En caso de que una actualización del entorno de producción hacia la automatización no se encuentre en tu lista de prioridades, Liquibase ofrece un host de comandos y operaciones que ayudarán a gestionar y ejecutar los changesets, tanto haciéndolo el mismo o generando el SQL que se ejecutará para que podamos revisarlo antes de la ejecución.

En conclusión…

Este artículo no pretende ser un tutorial de Liquibase, ni un manual para aprender a utilizarlo. Para ello recomiendo la documentación de su página oficial. Lee las mejores prácticas, ya que existen algunos patrones que puede que te hagan falta más tarde en el proyecto si no sabes cómo seguir avanzando.

Lo que quería mostrar es cómo puedes beneficiarte de Liquibase o de la inclusión de cualquier herramienta de migración de bases de datos en tu proceso de desarrollo, y así ser capaz de integrar cambios en el modelo en un sistema continuo de implantación/entrega, acercándose al flujo de trabajo DevOps.

TAGS: automated database, base de datos automatizada, database migration, liquibase, migración de base de datos

speech-bubble-13-icon Created with Sketch.
Comentarios

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*
*