DoctrineMigrationsBundle avec Symfony 3.1

symfony bundle

Appréhender l’évolution du schéma de la base de données est très important durant le cycle de vie d’un projet, car la base de données étant le cœur de notre produit nous devons avoir toutes les informations sur ses changements et pouvoir faire un rollback au moindre problème. DoctrineMigrationsBundle est un bundle doctrine qui nous permet donc de suivre cette évolution, de migrer la structure et les données de notre base de données, de manière sécurisée et standardisée.

Durant tout l’article nous allons considérer que vous  avez un projet Symfony déjà installé, si ce n’est pas le cas, cliquez sur le lien suivant http://symfony.com/download.

Nous verrons donc dans cet article, dans un environnement symfony 3, l’installation de ce bundle,  la prise en main et comment aller plus loin.

Installation et Configuration

  • Dans votre dossier de projet vous taper la commande :
php composer.phar require doctrine/doctrine-migrations-bundle dev-master
  • Une fois installé vous pouvez constater dans  votre fichier  composer.json la nouvelle ligne suivante :
"require": {
        "doctrine/doctrine-migrations-bundle": "dev-master"
    }
  • Dans le répertoire app/AppKernel.php nous allons ajouter la ligne de code suivante afin d'activer notre  nouveau bundle.
public function registerBundles()
{
    $bundles = array(
        //...liste des autres Bundles
        new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
    );
}
app/AppKernel.php
  • Maintenant que le bundle est installé  et activé, nous allons  le configurer dans app/config/config.yml.
# Doctrine Migrations Configuration
doctrine_migrations:
    dir_name: "%kernel.root_dir%/DoctrineMigrations" # Nom du dossier d'enregistrement des migrations.
    namespace: App\DoctrineMigrations                # namespaces des fichiers qui seront crées.
    table_name: migration_versions                   # Nom de la table d'enregistrement des versions de migrations
    name: App Migrations
config doctrine migrations

Prise en main

Pour  créer notre première migration nous avons  deux options qui s'offrent  à nous :

  • Créer notre migration de manière dynamique grâce à nos entités doctrine.
  • Créer notre migration manuellement grâce à nos fichiers sql.

Nous opterons pour la création dynamique car plus flexible et sécurisée, qui va nous permettre suivant l’évolution de nos entités de générer  des migrations à leurs images. Nous avons  aussi la possibilité d'y intégrer l'option manuelle afin de personnaliser à notre guise des traitements non pris en compte avec l'entité.

  • Création entité

Prenons donc l'exemple de l'entité suivante :

<?php

// src/AppBundle/Entity/User.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Class User
 *
 * @ORM\Entity
 * @ORM\Table(name="ms_user")
 */
class User
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="firstname", type="string", length=255)
     */
    private $firstname;

    /**
     * @var string
     *
     * @ORM\Column(name="lastname", type="string", length=255)
     */
    private $lastname;

    /**
     * @var string
     *
     * @ORM\Column(name="email", type="string", length=255, unique=true)
     */
    private $email;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set firstname
     *
     * @param string $firstname
     * @return Users
     */
    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;

        return $this;
    }

    /**
     * Get firstname
     *
     * @return string 
     */
    public function getFirstname()
    {
        return $this->firstname;
    }

    /**
     * Set lastname
     *
     * @param string $lastname
     * @return Users
     */
    public function setLastname($lastname)
    {
        $this->lastname = $lastname;

        return $this;
    }

    /**
     * Get lastname
     *
     * @return string 
     */
    public function getLastname()
    {
        return $this->lastname;
    }

    /**
     * Set email
     *
     * @param string $email
     * @return Users
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }

}

  • Génération du fichier de migration

Une fois l'entité créée nous allons faire un match afin de voir la différence avec notre base de données actuelle via la commande suivante, ce qui nous permettra de générer de manière dynamique une nouvelle migration en fonction de notre entité et de la base de données.

 php bin/console doctrine:migrations:diff
Générer une nouvelle migration automatiquement
  • Analyse du fichier de migration

La commande ci-dessus produira un fichier de migration dans app\DoctrineMigrations  que nous renommons Version00001_init_sql ayant le contenu ci-dessous :

<?php

namespace App\DoctrineMigrations;

use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;

/**
 * Version00001_init_sql.php initialisation
 */
class Version00001_init_sql extends AbstractMigration
{
    /**
     * Création de la table ms_user
     * @param Schema $schema
     */
    public function up(Schema $schema)
    {
      
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
        $this->addSql('CREATE TABLE ms_user (id INT AUTO_INCREMENT NOT NULL, firstname VARCHAR(255) NOT NULL, lastname VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_EC2FDC7BE7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');

    }

    /**
     * Roolback de la table ms_user précedente
     * @param Schema $schema
     */
    public function down(Schema $schema)
    {
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');      
        $this->addSql('DROP TABLE ms_user');
    }
}
Migration Version00001_init_sql.php
  • Exécution du fichier de migration

Vous pouvez effectuer différentes tâches sur un fichier de migration via  les commandes suivantes :

php app/console doctrine:migrations:migrate  # lance toutes les migrations non encore lancés
php app/console doctrine:migrations:execute 00001_init_sql # lance une unique migration avec son nom.
php app/console doctrine:migrations:execute 00001_init_sql --down # lance un rollback sur la migration00001_init_sql
Gestion migration

Pour aller plus loin

Afin d'appréhender la puissance de DoctrineMigrationsBundle,  nous vous listons les différentes tâches possibles :

  • Migration des données
  • Procédure stockée
  • Utiliser des queryBuilder doctrine
  • Utiliser des hooks  preUp(), postUp(), preDown(), and postDown() afin d'effectuer divers traitements avant et après l’exécution.

Conclusion

Afin de s'apercevoir de la puissance  et son utilité dans la mise en place d'un processus de qualité des déploiements de la base de données, il est préférable que vous le mettiez en place dès le début de votre projet.

Un commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *