Doctrine Migrations Bundle o actualizaciones de datos incrementales

Uno de los problemas que surgen cuando usamos DataFixtures o datos de pruebas es que creamos muchas fixtures para que la base de datos tenga la informacion necesaria antes de lanzar la aplicacion a producción y que pueda funcionar todo a la perfección para aquellas tablas  que solo contienen informacion acotada para campos <select> por ejemplo. Hasta aquí todo bien, es el procedimiento normal.

Ahora bien, imagínate que al cabo del tiempo y una vez has desplegado tu aplicacion en producción, necesitas modificar un valor de un campo y no puedes borrar el esquema de la base de datos porque obviamente ya existen datos que no podemos perder de nuestros usuarios etc.

Aquí entra en juego el bundle de Doctrine para hacer “migraciones” incrementales y os voy a explicar brevemente como usarlo.

-Instalar bundle

>>php composer.phar require doctrine/doctrine-migrations-bundle

-Inicializar bundle(AppKernel.php)

new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),

-Crear migraciones

>> php app/console doctrine:migrations:generate

este comando lo que hace basicamente es crear una clase PHP dentro del directorio por defecto app/DoctrineMigrations/ cuyo nombre empieza por Version y añade la fecha y hora del momento de creacion. Ademas, la clase incluye 2 metodos up() y down() donde implementaremos el cambio(up) y la forma de deshacerlo(down) por si quisieramos volver atras. Podemos implementar la interfaz para hacer uso del contenedor de dependencias.

-Ejemplo:

class Version20160523164637 extends AbstractMigration implements ContainerAwareInterface
{
    /** @var ContainerInterface $container */
    private $container;

    /**
     * @param ContainerInterface $container
     */
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * @param Schema $schema
     */
    public function up(Schema $schema)
    {
        // this up() migration is auto-generated, please modify it to your needs
        $documentationTypeManager = $this->container->get('documentation_type_manager');
        $docTypeDni = $documentationTypeManager->findOneByName('DNI');

        if($docTypeDni){
            $docTypeDni->setName('DNI/NIF');
            $documentationTypeManager->persistAndFlush($docTypeDni);
        }
    }

    /**
     * @param Schema $schema
     */
    public function down(Schema $schema)
    {
        // this down() migration is auto-generated, please modify it to your needs
        $documentationTypeManager = $this->container->get('documentation_type_manager');
        $docTypeDni = $documentationTypeManager->findOneByName('DNI/NIF');

        if($docTypeDni){
            $docTypeDni->setName('DNI');
            $documentationTypeManager->persistAndFlush($docTypeDni);
        }
    }
}

Aqui podemos hacer cambios de 3 formas distintas:

  • Usando servicios que trabajan con objetos directamente(Managers)
  • Usando el QueryBuilder del EntityManager
  • Usando el metodo $this->addSql(‘UPDATE table SET x=1’); . Esto vendra bien si tenemos procedimientos almacenados en nuestra BD y queremos llamarlos.

-Ejecutar una migración

>> php app/console doctrine:migrations:migrate

Si todo es correcto, a continuación nos aparecerá lo siguiente:

Ejecucion de una migracion

Si investigamos en la base de datos, nos habrá creado una nueva tabla donde aparecen las versiones que tenemos y que hemos aplicado en nuestra aplicación.

-Ver el estado de las migraciones

>> php app/console doctrine:migrations:status

Con este comando podemos ver la información de las migraciones en nuestra aplicación así:

estado

-Desahacer una migración

>> php app/console doctrine:migrations:execute YYYYMMDDHHIISS –down

De esta forma deshacemos una migración cambiando YYYYMMDDHHIISS por el valor que pone en CurrentVersion del comando status. Por eso es muy importante implementar el método down() de la clase, para que sepa como deshacer una migración y que cambios tendría que aplicar para que este como estaba antes de hacer la migración.

Resumen

Con esta herramienta tendremos un histórico de aquellos cambios en los datos de nuestra esquema que han sufrido cambios a posteriori de instalar nuestros fixtures al desplegar nuestra aplicacion. También sabremos quien a cambiado que, ya que al crearse una nueva clase en nuestro proyecto, sabremos quien la ha creado y el motivo.

Documentación

Si os ha gustado, no dudéis en compartir este post.

Saludos SymfoyDevs ¡

Anuncios