Migrations et Seeders sont de puissants utilitaires de base de données fournis par le cadre PHP de Laravel pour permettre aux développeurs d’amorcer, de détruire et de recréer rapidement la base de données d’une application. Ces utilitaires aident à minimiser les problèmes d’incohérence de la base de données qui peuvent survenir lorsque plusieurs développeurs travaillent sur la même application : les nouveaux contributeurs n’ont qu’à exécuter quelques commandes artisan
pour configurer la base de données lors d’une nouvelle installation.
Dans ce guide, nous allons créer des migrations et des seeders pour alimenter la base de données d’une application de démonstration de Laravel avec des exemples de données. À la fin, vous pourrez détruire et recréer les tables de votre base de données autant de fois que vous le souhaitez, en utilisant uniquement des commandes artisan
.
Pour suivre ce guide, vous aurez besoin :
Remarque : dans ce guide, nous utiliserons un environnement de développement conteneurisé géré par Docker Compose pour exécuter l’application, mais vous pouvez également opter pour la mise en oeuvre de l’application sur un serveur LEMP. Pour le configurer, vous pouvez suivre notre guide sur Comment installer et configurer Laravel avec LEMP sur Ubuntu 18.04.
Pour commencer, nous irons chercher l’application de démonstration Laravel dans son répertoire GitHub. Nous sommes intéressés par la branche tutoriel-02
, qui comprend une configuration Docker Compose pour exécuter l’application sur les conteneurs. Dans cet exemple, nous allons télécharger l’application dans notre dossier d’accueil, mais vous pouvez utiliser n’importe quel répertoire de votre choix :
- cd ~
- curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-2.0.1.zip -o travellist.zip
Parce que nous avons téléchargé le code d’application au format .zip
, nous aurons besoin de la commande unzip
pour le décompresser. Si vous ne l’avez pas fait récemment, mettez à jour l’index de package local de votre machine :
- sudo apt update
Ensuite, installez le package unzip
:
- sudo apt install unzip
Puis, décompressez le contenu de l’application :
- unzip travellist.zip
Renommez ensuite le répertoire décompressé en travellist-demo pour un accès plus facile :
- mv travellist-laravel-demo-tutorial-2.0.1 travellist-demo
Au cours de la prochaine étape, nous allons créer un fichier de configuration .env
pour configurer l’application.
.env
de l’applicationDans Laravel, un fichier .env
est utilisé pour mettre en place des configurations dépendantes de l’environnement, telles que les références et toute information qui pourrait varier d’un déploiement à l’autre. Ce fichier n’est pas inclus dans la gestion des versions.
Attention : le fichier de configuration de l’environnement contient des informations sensibles sur votre serveur, notamment les informations d’identification de la base de données et les clés de sécurité. Par conséquent, ne partagez jamais ce fichier en public.
Les valeurs contenues dans le fichier .env
auront la priorité sur les valeurs fixées dans les fichiers de configuration habituels situés dans le répertoire config
. Chaque installation sur un nouvel environnement nécessite un fichier d’environnement personnalisé pour définir des éléments tels que les paramètres de connexion à la base de données, les options de débogage, et l’URL de l’application, entre autres, qui peuvent varier en fonction de l’environnement dans lequel l’application est exécutée.
Naviguez vers le répertoire travellist-demo
:
- cd travellist-demo
Nous allons maintenant créer un nouveau fichier .env
afin de personnaliser les options de configuration pour l’environnement de développement que nous configurons. Laravel contient un exemple de fichier .env
que nous pouvons copier pour créer le nôtre :
- cp .env.example .env
Ouvrez ce fichier en utilisant nano
ou votre éditeur de texte préféré :
- nano .env
Voici à quoi ressemble désormais votre fichier .env
:
APP_NAME=Travellist
APP_ENV=dev
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=travellist
DB_USERNAME=travellist_user
DB_PASSWORD=password
…
Le fichier .env
actuel de l’application de démonstration travellist
contient les paramètres permettant d’utiliser l’environnement conteneurisé que nous avons créé avec Docker Compose dans la dernière partie de cette série. Vous n’avez besoin de modifier aucune de ces valeurs, mais vous êtes libre de modifier la DB_DATABASE
, DB_USERNAME
et DB_PASSWORD
si vous le souhaitez, car elles sont tirées par notre fichier docker-compose.yml
pour configurer automatiquement la base de données de développement. Assurez-vous simplement que la variable DB_HOST
reste inchangée, car elle fait référence au nom de notre service de base de données dans l’environnement Docker Compose.
Si vous apportez des changements au fichier, veillez à l’enregistrer et à le fermer en pressant CTRL+X
, Y
, puis ENTER
.
Remarque : si vous avez choisi de lancer l’application sur un serveur LEMP, vous devrez modifier les valeurs mises en évidence pour refléter les paramètres de votre propre base de données, y compris la variable DB_HOST
.
Nous allons maintenant utiliser Composer, l’outil de gestion des dépendances de PHP, pour installer les dépendances de l’application et nous assurer que nous sommes capables d’exécuter des commandes artisan
.
Appelez votre environnement Docker Compose avec la commande suivante. Cela permettra de construire l’image travellist
pour le service d’application
et d’intégrer les images Docker supplémentaires requises par les services nginx
et db
, afin de créer l’environnement de l’application :
- docker-compose up -d
OutputCreating network "travellist-demo_travellist" with driver "bridge"
Building app
Step 1/11 : FROM php:7.4-fpm
---> fa37bd6db22a
Step 2/11 : ARG user
---> Running in 9259bb2ac034
…
Creating travellist-app ... done
Creating travellist-nginx ... done
Creating travellist-db ... done
Cette opération peut prendre quelques minutes. Une fois le processus terminé, nous pouvons exécuter Composer pour installer les dépendances de l’application.
Pour exécuter composer
et les autres commandes du conteneur du service d’app
lication, nous utiliserons docker-compose exec
. La commande exec
nous permet d’exécuter toute commande de notre choix sur les conteneurs gérés par Docker Compose. Elle utilise la syntaxe suivante : docker-compose exec service_name command
.
Remarque : si vous avez choisi d’utiliser un serveur LEMP pour exécuter l’application de démonstration, vous devez ignorer la partie docker-compose exec application
des commandes énumérées dans ce guide. Par exemple, au lieu d’exécuter la commande suivante telle qu’elle est écrite, vous vous contenterez de lancer :
- composer install
Pour exécuter composer install
dans le conteneur d’application
, exécutez :
- docker-compose exec app composer install
OutputLoading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 85 installs, 0 updates, 0 removals
- Installing doctrine/inflector (1.3.1): Downloading (100%)
- Installing doctrine/lexer (1.2.0): Downloading (100%)
- Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%)
…
Lorsque Composer aura terminé d’installer les dépendances de l’application, vous pourrez exécuter des commandes artisan
. Pour vérifier que l’application est capable de se connecter à la base de données, exécutez la commande suivante qui nettoiera toutes les tables préexistantes :
- docker-compose exec app php artisan db:wipe
Cette commande va déposer toute table préexistante dans la base de données configurée. Si elle a été exécutée avec succès et que l’application est capable de se connecter à la base de données, vous verrez une sortie comme ceci :
OutputDropped all tables successfully.
Maintenant que vous avez installé les dépendances d’application avec Composer, vous pouvez utiliser l’outil artisan
pour créer des migrations et seeders.
L’outil de ligne de commande artisan
qui est livré avec Laravel contient une série de commandes d’aide qui peuvent être utilisées pour gérer l’application et démarrer de nouvelles classes. Pour générer une nouvelle classe de migration, nous pouvons utiliser la commande make:migration
comme suit :
- docker-compose exec app php artisan make:migration create_places_table
Laravel déduit l’opération à exécuter (create
), le nom de la table (places
), et si cette migration créera ou non une nouvelle table, en fonction du nom descriptif fourni à la commande make:migration
.
Vous verrez une sortie similaire à celle-ci :
OutputCreated Migration: 2020_02_03_143622_create_places_table
Cela va générer un nouveau fichier dans le répertoire database/migrations
de l’application. L’horodatage inclus dans le fichier généré automatiquement est utilisé par Laravel pour déterminer dans quel ordre les migrations doivent être exécutées.
Utilisez l’éditeur de texte de votre choix pour ouvrir le fichier de migration généré. N’oubliez pas de remplacer la valeur surlignée par votre propre nom de fichier de migration :
- nano database/migrations/2020_02_03_143622_create_places_table.php
Le fichier de migration généré contient une classe appelée CreatePlacesTable
:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePlacesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('places', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('places');
}
}
Cette classe a deux méthodes : up
et down
. Les deux méthodes contiennent du code de démarrage que vous pouvez étendre pour personnaliser ce qui se passe lorsque la migration est exécutée, et également ce qui se passe lorsqu’elle est annulée.
Nous allons modifier la méthode up
afin que le tableau places
reflète la structure que nous utilisons déjà dans la version actuelle de l’application :
id
: champ clé primaire.name
: nom de la placevisited
: si cette place a déjà été visitée ou non.Le constructeur de schémas de Laravel expose des méthodes pour créer, mettre à jour et supprimer des tables dans une base de données. La classe Blueprint
définit la structure du tableau et fournit plusieurs méthodes pour abstraire la définition de chaque champ de la table.
Le code généré automatiquement crée un champ d’identification primaire appelé id
. La méthode timestamps
crée deux champs datetime
qui sont automatiquement mis à jour par les classes de base de données sous-jacentes lorsque des données sont insérées ou mises à jour dans ce tableau. En plus de ceux-ci, nous devrons inclure un champ name
et un champ visited
.
Notre champ name
sera de type string
, et notre champ visited
sera défini avec le type boolean
. Nous allons également fixer une valeur par défaut de 0
pour le champ visited
, de sorte que si aucune valeur n’est passée, cela signifie que la place n’a pas encore été visitée. Voici à quoi ressemblera maintenant la méthode up
:
…
public function up()
{
Schema::create('places', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name', 100);
$table->boolean('visited')->default(0);
$table->timestamps();
});
}
…
Remarque : vous pouvez trouver la liste complète des types de colonnes disponibles dans la documentation Laravel.
Après avoir inclus les deux lignes sur votre propre script de migration, enregistrez et fermez le fichier.
Votre migration est maintenant prête à être exécutée via artisan migrate
. Cependant, cela ne créerait qu’un tableau vide ; nous devons également pouvoir insérer des échantillons de données pour le développement et les tests. Au cours de la prochaine étape, nous allons voir comment faire cela en utilisant une base de données seeders.
Un seeder est une classe spéciale utilisée pour générer et insérer des échantillons de données (seeds) dans une base de données. Il s’agit d’une caractéristique importante dans les environnements de développement, car elle permet de recréer l’application avec une base de données fraîche, en utilisant des valeurs d’échantillon que vous devriez autrement insérer manuellement à chaque fois que la base de données est recréée.
Nous allons maintenant utiliser la commande artisan
afin de générer une nouvelle classe seeder pour notre tableau places
appelé PlacesTableSeeder
:
- docker-compose exec app php artisan make:seeder PlacesTableSeeder
La commande va créer un nouveau fichier appelé PlacesTableSeeder.php
à l’intérieur du répertoire database/seeds
. Ouvrez ce fichier en utilisant l’éditeur de texte de votre choix :
- nano database/seeds/PlacesTableSeeder.php
Voici à quoi ressemble le fichier PlacesTableSeeder.php
généré automatiquement :
<?php
use Illuminate\Database\Seeder;
class PlacesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
}
}
Notre nouvelle classe seeder contient une méthode vide appelée run
. Cette méthode sera appelée lorsque la commande Artisan db:seed
sera exécutée.
Nous devons modifier la méthode run
afin d’inclure des instructions pour insérer des échantillons de données dans la base de données. Nous utiliserons le constructeur de requêtes de Laravel pour rationaliser ce processus.
Le constructeur de requêtes Laravel offre une interface fluide pour les opérations de base de données telles que l’insertion, la mise à jour, la suppression et la récupération des données. Il introduit également des protections contre les attaques par injection SQL. Le constructeur de requête est exposé par la façade DB
- un proxy statique aux classes de base de données sous-jacentes dans le conteneur de service.
Pour commencer, nous allons créer une variable de classe statique pour contenir tous les échantillons que nous voulons insérer dans la base de données sous la forme d’un tableau. Cela nous permettra d’utiliser une boucle foreach
pour itérer toutes les valeurs, en insérant chacune d’entre elles dans la base de données à l’aide du constructeur de requêtes.
Nous allons appeller cette variable $places
:
<?php
use Illuminate\Database\Seeder;
class PlacesTableSeeder extends Seeder
{
static $places = [
'Berlin',
'Budapest',
'Cincinnati',
'Denver',
'Helsinki',
'Lisbon',
'Moscow',
'Nairobi',
'Oslo',
'Rio',
'Tokyo'
];
…
Ensuite, nous devrons inclure une déclaration use
en haut de notre classe PlacesTableSeeder
pour faciliter le référencement de la façade DB
dans tout le code :
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class PlacesTableSeeder extends Seeder
…
Nous pouvons maintenant itérer les valeurs du tableau $places
à l’aide d’une boucle foreach
, et insérer chacune d’entre elles dans notre tableau places
en utilisant le constructeur de requêtes :
…
public function run()
{
foreach (self::$places as $place) {
DB::table('places')->insert([
'name' => $place,
'visited' => rand(0,1) == 1
]);
}
}
La boucle foreach
se passe par chaque valeur du tableau statique $places
. À chaque itération, nous utilisons la façade DB
pour insérer une nouvelle rangée au tableau places
. Nous avons défini le champ name
au nom de la place que nous venons d’obtenir à partir du tableau $places
, et nous avons défini le champ visited
à une valeur aléatoire de 0
ou 1
.
Voici à quoi ressemblera la classe PlacesTableSeeder
complète après toutes les mises à jour :
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class PlacesTableSeeder extends Seeder
{
static $places = [
'Berlin',
'Budapest',
'Cincinnati',
'Denver',
'Helsinki',
'Lisbon',
'Moscow',
'Nairobi',
'Oslo',
'Rio',
'Tokyo'
];
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
foreach (self::$places as $place) {
DB::table('places')->insert([
'name' => $place,
'visited' => rand(0,1) == 1
]);
}
}
}
Enregistrez et fermez le fichier lorsque vous avez terminé de procéder à ces changements.
Les classes Seeder ne sont pas automatiquement chargées dans l’application. Nous devons modifier la classe DatabaseSeeder
principale pour inclure un appel au seeder que nous venons de créer.
Ouvrez le fichier database/seeds/DatabaseSeeder.php
à l’aide de nano
ou de votre éditeur préféré :
- nano database/seeds/DatabaseSeeder.php
La classe DatabaseSeeder
ressemble à n’importe quel autre seeder : elle s’étend depuis la classe Seeder
et a une méthode run
. Nous allons mettre à jour cette méthode pour inclure un appel à PlacesTableSeeder
.
Mettez à jour la méthode run
actuelle dans votre classe DatabaseSeeder
en supprimant la ligne commentée et en la remplaçant par le code sélectionné qui suit :
…
public function run()
{
$this->call(PlacesTableSeeder::class);
}
...
Voici à quoi ressemblera la classe DatabaseSeeder
complète après la mise à jour :
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(PlacesTableSeeder::class);
}
}
Enregistrez et fermez le fichier lorsque vous avez terminé de mettre à jour son contenu.
Nous avons maintenant terminé de créer à la fois une migration et un seeder pour notre tableau places
. Au cours de la prochaine étape, nous allons voir comment les exécuter.
Avant de poursuivre, nous devons nous assurer que votre application est opérationnelle. Nous allons configurer la clé de cryptage de l’application, puis accéder à l’application à partir d’un navigateur pour tester le serveur web.
Pour générer la clé de cryptage requise par Laravel, vous pouvez utiliser la commande artisan key:generate
:
- docker-compose exec app php artisan key:generate
Une fois la clé générée, vous pourrez accéder à l’application en pointant votre navigateur vers votre serveur hostname ou votre adresse IP sur le port 8000
:
http://server_host_or_ip:8000
Vous verrez une page comme celle-ci :
Cela signifie que l’application est capable de se connecter à la base de données, mais qu’elle n’a pu trouver le tableau places
. Nous allons créer maintenant le tableau places
, en utilisant la commande artisan migrate
suivante :
- docker-compose exec app php artisan migrate
Vous aurez une sortie similaire à celle-ci :
OutputMigration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.06 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.06 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds)
Migrating: 2020_02_10_144134_create_places_table
Migrated: 2020_02_10_144134_create_places_table (0.03 seconds)
Vous remarquerez que quelques autres migrations ont été exécutées en même temps que la migration create_places_table
que nous avons mise en place. Ces migrations sont générées automatiquement lors de l’installation de Laravel. Même si nous n’utiliserons pas ces tableaux supplémentaires maintenant, ils seront nécessaires à l’avenir lorsque nous étendrons l’application pour inclure des utilisateurs enregistrés et des jobs programmés. Pour l’instant, vous pouvez simplement les laisser tels quels.
À ce stade, notre tableau est toujours vide. Nous devons exécuter la commande db:seed
pour seeder la base de données avec notre échantillon de places :
- docker-compose exec app php artisan db:seed
Cela va exécuter notre seeder et insérer les échantillons des valeurs que nous avons définies dans notre classe PlacesTableSeeder
. Vous verrez une sortie similaire à celle-ci :
OutputSeeding: PlacesTableSeeder
Seeded: PlacesTableSeeder (0.06 seconds)
Database seeding completed successfully.
Maintenant, rechargez la page de l’application sur votre navigateur. Vous verrez une page similaire à celle-ci :
Chaque fois que vous devez repartir de zéro, vous pouvez déposer tous vos tableaux de base de données avec :
- docker-compose exec app php artisan db:wipe
OutputDropped all tables successfully.
Pour lancer les apps de migration et seeder les tableaux en une seule commande, vous pouvez utiliser :
- docker-compose exec app php artisan migrate --seed
OutputMigration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.06 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.07 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds)
Migrating: 2020_02_10_144134_create_places_table
Migrated: 2020_02_10_144134_create_places_table (0.03 seconds)
Seeding: PlacesTableSeeder
Seeded: PlacesTableSeeder (0.06 seconds)
Database seeding completed successfully.
Si vous voulez annuler une migration, vous pouvez exécuter :
- docker-compose exec app php artisan migrate:rollback
Cela déclenchera la méthode down
pour chaque classe de migration dans le dossier migrations
. En général, cela supprime tous les tableaux qui ont été créées par les classes de migration, en ignorant tous les autres tableaux qui auraient pu être créés manuellement. Vous verrez une sortie de ce type :
OutputRolling back: 2020_02_10_144134_create_places_table
Rolled back: 2020_02_10_144134_create_places_table (0.02 seconds)
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back: 2019_08_19_000000_create_failed_jobs_table (0.02 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_100000_create_password_resets_table (0.02 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back: 2014_10_12_000000_create_users_table (0.02 seconds)
La commande rollback est particulièrement utile lorsque vous apportez des modifications aux modèles d’application et qu’une commande db:wipe
ne peut pas être utilisée - par exemple, si plusieurs systèmes dépendent de la même base de données.
Dans ce guide, nous avons vu comment utiliser les bases de données migrations et seeders afin faciliter la mise en place de bases de données de développement et de test pour une application Laravel 6.
Pour continuer, vous pourriez consulter la documentation de Laravel pour plus de détails sur la façon d’utiliser le constructeur de requêtes et d’utiliser les modèles Eloquent afin d’abstraire encore davantage le schéma de la base de données de votre application.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!