Laravel: Migrations et ensemencement pour les données de production

mon application a besoin d'un ensemble de données préenregistrées pour fonctionner. J'ai donc besoin de les insérer dans la base de données lorsque j'ai créé la demande.

Laravel proposent deux mécanismes :

  • migration de la base de données : " ils permettent à une équipe de modifier le schéma de la base de données et de rester à jour sur l'état actuel du schéma."
  • base de données le semis : " Laravel inclut également un moyen simple pour ensemencer votre base de données avec des données d'essai en utilisant des classes de semences."

lorsque j'ai lu cette description, aucune de ces solutions ne semble adaptée.

une question similaire a été posée sur stackoverflow et répondu . La réponse propose d'utiliser le seeder de base de données a pour peupler la base de données en détectant environnement actuel:

<?php

class DatabaseSeeder extends Seeder {

    public function run()
    {
            Eloquent::unguard();

            if (App::environment() === 'production')
            {
                $this->call('ProductionSeeder');
            }
            else
            {
                $this->call('StagingSeeder');
            }
    }

}

bien sûr, cette solution fonctionne. Mais je ne suis pas sûr que ce soit la bonne façon de le faire, parce qu'en insérant des données en utilisant des seeders vous perdez tous les avantages fournis par le mécanisme de migration (base de données upgrate, roll back...)

je veux savoir quelle est la meilleure pratique dans ce cas.

32
demandé sur Community 2014-02-05 18:32:19

2 réponses

Laravel développement est une question de liberté. Donc, si vous avez besoin de semer votre base de données de production et de penser DatabaseSeeder est le meilleur endroit pour le faire, pourquoi pas?

d'accord, seeder est principalement à utiliser avec les données de test, mais vous verrez certaines personnes l'utilisant comme vous êtes.

je vois ce type important de graine dans le cadre de ma migration, puisque c'est quelque chose qui ne peut pas être hors de mes tables de base de données et artisan migrate est lancé chaque fois que je déploie une nouvelle version de ma demande, je viens donc de ne

php artisan migrate:make seed_models_table

et créer ma substance seedind en elle:

public function up()
{
    $models = array(
        array('name' => '...'),
    );

    DB::table('models')->insert($models);
}
52
répondu Antonio Carlos Ribeiro 2014-02-05 15:00:05

je me suis souvent demandé quelle était la bonne réponse. Personnellement, j'éviterais d'utiliser l'ensemencement pour peupler les lignes requises dans la base de données car vous devrez mettre une charge de logique conditionnelle pour vous assurer que vous n'essayez pas de peupler quelque chose qui est déjà là. (Supprimer et recréer les données est très déconseillé car vous pourriez finir avec des inadéquations de clés et si vous utilisez des suppressions en cascade vous pouvez accidentellement essuyer une charge de votre la base de données de mon erreur! ;- )

j'ai mis le 'ensemencement' des lignes dans le script de migration comme il y a des chances, les données devront être là dans le cadre du processus de déploiement.

il est intéressant de noter que vous devriez utiliser la classe DB au lieu de Modèles éloquents pour peupler ces données car votre structure de classe pourrait changer au fil du temps qui vous empêchera alors de recréer la base de données à partir de zéro (sans réécrire l'histoire et vous changer les fichiers de migration, ce dont je suis sûr, c'est une mauvaise chose.)

je dirais quelque chose comme ça:

public function up()
{
    DB::beginTransaction();

    Schema::create(
        'town',
        function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        }
    );

    DB::table('town')
        ->insert(
            array(
                array('London'),
                array('Paris'),
                array('New York')
            )
        );

    Schema::create(
        'location',
        function (Blueprint $table) {
            $table->increments('id');
            $table->integer('town_id')->unsigned()->index();
            $table->float('lat');
            $table->float('long');
            $table->timestamps();

            $table->foreign('town_id')->references('id')->on('town')->onDelete('cascade');
        }
    );

    DB::commit();
}

cela me permet alors de "semer" facilement la table de ville quand je l'ai créée, et n'interférera pas avec tous les ajouts faits à elle au temps de course.

27
répondu Dan B 2014-06-13 13:29:17