K

- Base de connaissances

Accueil > Langages de programmation > PHP > LARAVEL - Schéma Builder - Base de données

LARAVEL - Schéma Builder - Base de données

mardi 30 décembre 2014, par webmestre

Introduction

Dans cet article, nous allons mettre en place un exemple simple sous SQLLite pour documenter le concept de migration dans LARAVEL en créant une table users.

Configurer la base de données

Dans un premier temps, nous avons besoin de paramétrer l’accès à la base de données. C’est donc le pré-requis avoir une base de données opérationnelle avec les bons droits d’accès...

Et, comme évoqué en introduction, nous mettrons en oeuvre une base de données SQLite (ainsi pas besoin d’installer des serveur type SQLServer ou PostGreSQL, ...) pour documenter le concept dit de migration dans LARAVEL.


Information : LARAVEL supporte plusieurs types de bases de données grâce au connecteur PDO.

Pour paramétrer l’accès à la base de données, il suffit d’éditer le fichier de configuration app/config/database.php qui est un tableau tel que par défaut :

<?php
return array(
        'fetch' => PDO::FETCH_CLASS,
        'default' => 'mysql',
        'connections' => array(
                'sqlite' => array(
                        ......
                ),
                'mysql' => array(
                        ......
                ),
                'pgsql' => array(
                        ......
                ),
                'sqlsrv' => array(
                        ......
                ),
        ),
        'migrations' => 'migrations',
        'redis' => array(
                        ......
        ),
);

En détaillant le signification de chaque clef de ce tabelau, nous avons :

Clef Type Description
fetchObjet / ClasseObjet / Classe contenant le résultat des requêtes SQL, et par défaut l’objet est PDO ::FETCH... Et, il peut-être adapté fonction d’un besoin spécifique de développement en écrivant son propre objet de résultat
defaultChaîne de caractèresBase de données utilisées (Référence à une clef du tableau connections)
connectionsTableauChaque sous-tableau définit les accès à une base de données tel que MySQL, PostGreSQL, SQLServer,... les sous clef possible est un nom de base de données qui contient les paramètres de connexions à une base de donnée sqlite, mysql, pgsql, sqlsrv,... et de façon plus générale tous les connecteurs compatibles avec la technologie PDO
migrationsChaîne de caractèresChemin d’accès au répertoire de stockage des fichiers de codes sources permettant de migrer les tables de la base de données
redisTableauSous-tableau permettant de paramétrer les accès à l’Open Source REDIS, un serveur de structure de données... pour un accès plus rapide aux données via une gestion de leur indexation (cf. par exemple au BIGDATA)

Dans, notre exemple nous allons donc utiliser SQLLite, car très simple à mettre en oeuvre, d’où le fichier app/config/database.php  :

<?php
return array(
        'fetch' => PDO::FETCH_CLASS,
        'default' => 'MaBaseSQLLite',
        'connections' => array(
                'MaBaseSQLLite' => array(
                        'driver'   => 'sqlite',
                        'database' => __DIR__.'/../database/production.sqlite',
                        'prefix'   => '',
                ),
        ),
        'migrations' => 'migrations',
        'redis' => array(),
);

Créer les fichiers de migration

Comme déjà évoqué dans d’autres articles, on utilise l’API artisan pour créer les différents fichiers template (à partir de fichiers .stub) utiles à la mise en oeuvre du concept Migration. Pour se faire, on se place à la racine de son site WEB en cours de développement et on exécute la commande suivante qui indique que nous souhaitons créer la table users et que le source PHP de création soit nommé *create_users_table* :

php artisan migrate:make create_users_table --create=users

En exécutant, cette commande le fichier app/database/migration/_create_users_table.php a été créé. Son contenu est le suivant :

<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration {
        /**
         * Run the migrations.
         *
         * @return void
         */

        public function up()
        {
                Schema::create('users', function(Blueprint $table)
                {
                        $table->increments('user_id');
                        $table->string('login')->nullable(false);
                        $table->string('name')->nullable(false)->default("unknow");
                        $table->timestamps();
                });
        }
        /**
         * Reverse the migrations.
         *
         * @return void
         */

        public function down()
        {
                Schema::drop('users');
        }
}

Cette dernière commande génère un template de source PHP qui permettra de créer une table users dans la base de données, si nous migrons ce script en base de données via la commande suivante :

php artisan migrate

Et que nous regardons en base de données, là nous pouvons constater que 2 tables ont été créées :

  • Notre table users qui contient les champs mentionnées ci-dessus
  • Et le table migration qui contient les champs : migration et batch

Cette table migration est l’historique de contrôle des montées de version de la base de données. En exécutant la commande de migration ci-dessous, on invoque la méthode up de la classe Migration (= On monte de version).

Et, en exécutant la commande de rollback, on invoque la méthode down de la classe Migration (= On descend de version).

php artisan migrate:rollback

Ces commandes définissent les scripts de bases qui nous permettrons de créer ou modifier les tables de la base de données.


Point important :

  • les premiers caractères en gras du fichier _create_users_table.php (Par exemple : 2014_12_30_204456) est, certe une date, mais sutout un identifiant qui est généré à l’exécution de l’instruction migration:make. Il est vivement déconseillé de la modifier si vous souhaitez utiliser correctement les outils porposés par l’API artisan.
  • Le nom du fichier donné create_users_table sert aussi dans la création du nom de la classe du fichier _create_users_table.php, le nom de la classe et le nom du fichier sont indissociables. l’API Artisan détecte l’identifiant et génère un nom de classe propre.

Ajouter des données de tests : seed

Maintenant que nous avons une base de données avec une table migrée. Il serait utile de l’alimenter avec un jeu de données de tests. Pour se faire, et toujours dans la même philisophie, l’outillage existe. C’est le concept dit de seed, un objet permettant d’ensemencer la base de données.

Pour se faire, nous allons créer le fichier app/database/migration/seeds/UserTableSeeder.php, tel que :

<?php
class UserTableSeeder extends Seeder {
 
  public function run()
  {
      DB::table('users')->delete();
 
      User::create(array(
          'login' => 'user1'
      ));
 
      User::create(array(
          'login' => 'user2',
          'name' => 'know'
      ));
  }
 
}

Puis, nous allons ajouter la ligne suivante dans le fichier app/database/migration/seeds/DatabaseSeeder.php :

$this->call('UserTableSeeder');

Tel que :

<?php
class DatabaseSeeder extends Seeder {
        /**
         * Run the database seeds.
         *
         * @return void
         */

        public function run()
        {
                Eloquent::unguard();
                $this->call('UserTableSeeder');
        }
}

Enfin, en exécutant la commande suivante, nous "ensemençons" la base de données :

php artisan db:seed

Pour aller plus loin...

En jouant un peu avec cet outillage, vous allez rapidement constater ces limites en particuliers dans le nommage des fichiers et des classes (Vous ne pouvez pas avoir deux classes de même noms dans vos fichiers de migrations). La bonne pratique est en effet d’industrialiser le versionning sur la base de données pour permettre de travailler à plusieurs sur un même développement. Mais, il est nécessaire de mettre en place d’autres régles de nommage pour éviter un conflit de noms de classe.

Pour compléter l’exemple ci-dessus, et donc mettre en place une autre règle dans mes bonnes pratiques de développement qui me permettra d’éviter tout conflit de noms de classe. je vais poser comme règle :

  • Tous mes fichiers de migration se nommeront version_db_

tel que, je pourrai avoir les fichiers suivants :

1 - J’exécute la commande suivante :

php artisan migrate:make Version_DB_001 --create=users

Et, je modifie le fichier app/database/migration/_Version_DB_001.php (Je crée 2 tables ici ce que ne permet pas de faire la commande ci-dessus) :

 
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class VersionDB001 extends Migration {
        /**
         * Run the migrations.
         *
         * @return void
         */

        public function up()
        {
                Schema::create('users', function(Blueprint $table)
                {
                        $table->increments('user_id');
                        $table->string('login')->nullable(false);
                        $table->string('name')->nullable(false)->default("unknow");
                        $table->timestamps();
                });
                Schema::create('passwords', function(Blueprint $table)
                {
                        $table->increments('user_id');
                        $table->string('pwd')->nullable(false);
                        $table->timestamps();
                });
        }
        /**
         * Reverse the migrations.
         *
         * @return void
         */

        public function down()
        {
                Schema::drop('users');
                Schema::drop('passwords');
        }
}

2 - Je crée le Seeder app/database/migration/seeds/VersionDBSeeder001.php (Un nom de fichier sans underscore c’est la norme pour les Seeder sous Laravel), tel que :

 
<?php
class VersionDBSeeder001 extends Seeder {
 
  public function run()
  {
      DB::table('users')->delete();
 
      User::create(array(
          'login' => 'user1',
      ));
 
      User::create(array(
          'login' => 'user2',
          'name' => 'know'
      ));
  }
 
}

3 - Ensuite, je souhaite modifier ma base de données (ajouter un champ à ma table users et créer une nouvelle table adress), et je vais utiliser la commande suivente :

php artisan migrate:make Version_DB_002 --table=users

Et, je modifie le fichier app/database/migration/_Version_DB_002.php, tel que :

 
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class VersionDB002 extends Migration {
        /**
         * Run the migrations.
         *
         * @return void
         */

        public function up()
        {
                Schema::table('users', function(Blueprint $table)
                {
                        $table->string('pseudo')->nullable(false)->default("unknow");
                });
                Schema::create('adress', function(Blueprint $table)
                {
                        $table->increments('user_id');
                        $table->string('adress');
                        $table->string('city');
                });
        }
        /**
         * Reverse the migrations.
         *
         * @return void
         */

        public function down()
        {
                Schema::table('users', function(Blueprint $table)
                {
//                      $table->dropColumn('pseudo'); => dropColumn n'est pas supporté par SQLLite ;)
                        $table->string('name')->nullable(false)->default("unknow");
                });
        }
}

4 - Enfin, il suffit d’écrier le Seeder qui convient pour peupler la base de données app/database/migration/seeds/VersionDBSeeder002.php (et ne pas oublier de modifier le fichier app/database/migration/seeds/DatabaseSeeder.php) :

Liens utiles

Documentation LARAVEL du concept migration
Documentation LARAVEL de la classe Schema

Répondre à cet article

Plan du site | Suivre la vie du site RSS 2.0 | powered by NYSTEK-EDITIONS and NYSTEK-CONSULTING