Подтвердить что ты не робот

Laravel: Migrations & Seeding для производственных данных

Моему приложению нужен предварительно зарегистрированный набор данных для работы. Поэтому мне нужно вставить их в базу данных при настройке приложения.

Laravel предлагает два механизма:

  • Миграции базы данных: "Они позволяют команде изменять схему базы данных и оставаться в курсе текущего состояния схемы".
  • Заполнение базы данных: "Laravel также включает в себя простой способ заполнить вашу базу данных тестовыми данными, используя начальные классы".

Когда я читаю это описание, ни одно из этих решений не кажется адаптированным.

Подобный вопрос был qaru.site/info/188263/... и ответил. В ответе предлагается использовать сеялку базы данных для заполнения базы данных путем определения текущей среды:

<?php

class DatabaseSeeder extends Seeder {

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

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

}

Конечно, это решение работает. Но я не уверен, что это правильный способ сделать это, потому что, вставляя данные с помощью сеялок, вы теряете все преимущества механизма миграции (обновление базы данных, откат...)

Я хочу знать, что является лучшей практикой в этом случае.

4b9b3361

Ответ 1

Развитие Ларавеля - это свобода. Итак, если вам нужно засеять свою производственную базу данных и подумайте, что DatabaseSeeder - лучшее место для этого, почему бы и нет?

Хорошо, сеялка в основном используется с тестовыми данными, но вы увидите, как некоторые люди используют ее так, как вы.

Я вижу этот важный вид семян как часть моей миграции, поскольку это то, что не может быть из моих таблиц базы данных, и artisan migrate запускается каждый раз, когда я развертываю новую версию своего приложения, поэтому я просто делаю

php artisan migrate:make seed_models_table

И создайте в нем мои семена:

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

    DB::table('models')->insert($models);
}

Ответ 2

Я часто задавался вопросом, какой правильный ответ на это. Лично я избегаю использования семян для заполнения требуемых строк в базе данных, так как вам придется наложить нагрузку условной логики, чтобы убедиться, что вы не пытаетесь заполнить что-то, что уже есть. (Удаление и повторное создание данных очень нецелесообразно, так как вы можете столкнуться с несоответствиями клавиш, и если вы используете каскадные удаления, вы можете случайно стереть нагрузку своей базы данных на мою ошибку! -)

Я помещаю "посев" строк в перенос script, так как это возможно, данные должны быть там как часть процесса развертывания.

Стоит отметить, что вы должны использовать класс DB вместо моделей Eloquent для заполнения этих данных, поскольку ваша структура классов может со временем меняться, что не позволит вам повторно создавать базу данных с нуля (без перезаписи истории и изменения миграции файлы, которые, я уверен, являются плохими.)

У меня бы получилось что-то вроде этого:

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();
}

Это позволяет мне легко "посеять" городской стол, когда я его впервые создаю, и не буду вмешиваться в какие-либо дополнения, сделанные им во время выполнения.

Ответ 3

Это то, что я использую в производстве.

Так как я запускаю миграцию на каждом развертывании

artisan migrate

Я создаю сеялку (просто чтобы не допустить посева данных из-под миграции для облегчения доступа позже), а затем запускаю эту сеялку вместе с миграцией

class YourTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {    
        //migrate your table // Example
        Schema::create('test_table', function(Blueprint $table)
        {
            $table->increments('id');
            $table->timestamps();
            $table->softDeletes();
        });

        //seed this table
        $seeder = new YourTableSeeder();
        $seeder->run();
    }

    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down()
    {
        Schema::drop('test_table');
    }
}

Я не добавляю этот начальный вызов в seed/DatabaseSeeder.php, чтобы не запускать его дважды при новой установке.