
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é.
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