Как запустить Laravel migration и DB seeder, кроме одного

У меня много файлов миграции и сеялки для запуска, хотя мне нужно будет запустить все файлы, но в настоящее время мне нужно пропустить одну миграцию и сеялку.

Как я могу пропустить один файл из команды Laravel migration и db seeder.

Я не хочу удалять файлы из папки миграции или семян, чтобы пропустить файл.

7 ответов


Laravel не дает вам метод по умолчанию для этого. Однако для этого можно создать собственные консольные команды и сеялку.
Допустим, у вас есть это значение по умолчанию DatabaseSeeder класс:

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(ExampleTableSeeder::class);
        $this->call(UserSamplesTableSeeder::class);
    }
}

цель состоит в том, чтобы создать новую команду, переопределяющую "db: seed" и передать новый параметр, параметр "except", в DatabaseSeeder класса.

это окончательный код, я создал на своем экземпляре Laravel 5.2 и попробовал:

команда, положить в app / Console / Commands, не забудьте обновить ядро.на PHP:

namespace App\Console\Commands;
use Illuminate\Console\Command;
class SeedExcept extends Command
{
    protected $signature = 'db:seed-except {--except=class name to jump}';
    protected $description = 'Seed all except one';
    public function handle()
    {
        $except = $this->option('except');
        $seeder = new \DatabaseSeeder($except);
        $seeder->run();
    }
}

DatabaseSeeder

use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
    protected $except;

    public function __construct($except = null) {
        $this->except = $except;
    }

    public function call($class)
    {
        if ($class != $this->except)
        {
            echo "calling $class \n";
            //parent::call($class);  // uncomment this to execute after tests
        }
    }

    public function run()
    {
        $this->call(ExampleTableSeeder::class);
        $this->call(UserSamplesTableSeeder::class);
    }
}

это код, вы найдете, что я прокомментировал строку, которая вызывает семя и добавила Эхо для целей тестирования.

выполнение этой команды:

php artisan db: seed-кроме

даст вам:

вызов ExampleTableSeeder
вызов UserSamplesTableSeeder

однако, добавив "за исключением":

php artisan db: seed-except --except=ExampleTableSeeder

даст вам

вызов UserSamplesTableSeeder

это работает, переопределяя значение по умолчанию call метод DatabaseSeeder class и вызов родителя, только если имя класса не находится в переменной $except. Переменная заполняется параметром SeedExcept таможня команда.

что касается миграции, то это похоже, но немного сложнее.

я не могу дать вам проверенный код для этого сейчас, но дело в том, что:

  • создать migrate-except команда, которая переопределяет MigrateCommand class (пространство имен освещает\Database\Console\Migrations, расположенное в vendor/laravel/framework/src/Illuminate/Database/Console/Migrations / MigrateCommand.РНР.)
  • the MigrateCommand принимает Migrator объект (пространство имен загорается\\базы данных миграций, путь поставщика/фреймворк Laravel/рамках/в src/освещения/базы данных/миграция/поддержка всех текущих.php) в конструкторе (вводится через IoC). The Migrator класс владеет логикой, которая считывает все миграции внутри папки и выполняет ее. Эта логика находится внутри run() метод
  • создать подкласс Migrator, например MyMigrator и переопределить run() метод пропустить файлы, переданные с помощью специальной опции
  • переопределить __construct() метод MigrateExceptCommand и MyMigrator: public function __construct(MyMigrator $migrator)

если у меня есть время, я добавлю код для примера, прежде чем баунти закончится

EDIT как и было обещано, вот пример миграции:

класс MyMigrator, расширяет Migrator и содержит логику для пропуска файлов:

namespace App\Helpers;
use Illuminate\Database\Migrations\Migrator;
class MyMigrator extends Migrator
{
    public $except = null;

    // run() method copied from it's superclass adding the skip logic
    public function run($path, array $options = [])
    {
        $this->notes = [];

        $files = $this->getMigrationFiles($path);

        // skip logic
        // remove file from array
        if (isset($this->except))
        {
            $index = array_search($this->except,$files);
            if($index !== FALSE){
                unset($files[$index]);
            }
        }
        var_dump($files); // debug

        $ran = $this->repository->getRan();
        $migrations = array_diff($files, $ran);
        $this->requireFiles($path, $migrations);

        //$this->runMigrationList($migrations, $options);  // commented for debugging purposes
    }
}

пользовательская команда MigrateExcept

namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Console\Migrations\MigrateCommand;
use App\Helpers\MyMigrator;
use Illuminate\Database\Migrations\Migrator;
use Symfony\Component\Console\Input\InputOption;

class MigrateExcept extends MigrateCommand
{
    protected $name = 'migrate-except'; 

    public function __construct(MyMigrator $migrator)
    {   
        parent::__construct($migrator);
    }

    public function fire()
    {
        // set the "except" param, containing the name of the file to skip, on our custom migrator
        $this->migrator->except = $this->option('except');
        parent::fire();
    }

    // add the 'except' option to the command
    protected function getOptions()
    {
        return [
            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'],

            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],

            ['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'],

            ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'],

            ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'],

            ['step', null, InputOption::VALUE_NONE, 'Force the migrations to be run so they can be rolled back individually.'],

            ['except', null, InputOption::VALUE_OPTIONAL, 'Files to jump'],
        ];
    }
}

наконец, вам нужно добавить это в службу поставщик, чтобы разрешить Laravel IoC разрешить зависимости

namespace App\Providers;
use App\Helpers\MyMigrator;
use App\Console\Commands\MigrateExcept;


class CustomServiceProvider extends ServiceProvider
{
    public function boot()
    {
        parent::boot($events);

        $this->app->bind('Illuminate\Database\Migrations\MigrationRepositoryInterface', 'migration.repository');
        $this->app->bind('Illuminate\Database\ConnectionResolverInterface', 'Illuminate\Database\DatabaseManager');

        $this->app->singleton('MyMigrator', function ($app) {
            $repository = $app['migration.repository'];
            return new MyMigrator($repository, $app['db'], $app['files']);
        });
    }
}

не забудьте добавить Commands\MigrateExcept::class в ядре.в PHP

теперь, если вы выполните

php artisan migrate-кроме

у вас есть:

array(70) {
  [0] =>
  string(43) "2014_04_24_110151_create_oauth_scopes_table"
  [1] =>
  string(43) "2014_04_24_110304_create_oauth_grants_table"
  [2] =>
  string(49) "2014_04_24_110403_create_oauth_grant_scopes_table"
  ...

но добавив кроме param:

php artisan migrate-except --except=2014_04_24_110151_create_oauth_scopes_table

array(69) {
  [1] =>
  string(43) "2014_04_24_110304_create_oauth_grants_table"
  [2] =>
  string(49) "2014_04_24_110403_create_oauth_grant_scopes_table"

так, резюме:

  • мы создаем пользовательскую миграцию-кроме команды,MigrateExcept класс, расширение MigrateCommand
  • мы создаем пользовательский класс migrator,MyMigrator, расширяя поведение стандарта Migrator
  • когда MigrateExcept является fire (), передайте имя файла, чтобы перейти к нашему MyMigrator класс
  • MyMigrator переопределяет run() метод Migrator и пропустить пройденную миграцию
  • больше: так как нам нужно проинструктировать Laravel IoC о новых созданных классах, чтобы он мог правильно их вводить, мы создаем поставщика услуг

код протестирован, поэтому он должен работать правильно на Laravel 5.2 (надеясь, что cut&paste работал правильно :-) ...если у кого-то есть сомнения, оставьте комментарий


пропуск семян очень прост, миграций не так много. Чтобы пропустить семя, удалите следующее из класса DatabaseSeeder.

$this->call(TableYouDontWantToSeed::class);

для миграции есть три способа сделать это:

  • поместите класс, который вы не хотите переносить в другую папку.
  • вставить перенос в базу данных вручную (ответ Bindesh Пандья разработали).
  • переименуйте файл, который вы не хотите переносить на что-то вроде UsersTableMigration.dud.

надеюсь, что это помогает


Я также столкнулся с той же проблемой в моем проекте, но после долгого времени в R & D я обнаружил, что Laravel не предоставляет никакого способа сделать это с миграцией и посевом, но у вас есть 2 способа сделать это.

1) вы сэкономите много времени, просто помещая их в разные папки. Теоретически вы могли бы сделайте свою собственную команду ремесленника что делает ты хочешь, или подделывает его, создавая каталоги, перемещая файлы и выполняя в PHP ремесленника мигрировать.

для сеялок просто сделайте сеялку и вызовите другие сеялки, от которых вы хотите убежать. Тогда просто будьте откровенны о том, какой сеялка вы хотите запустить. Попробуйте php artisan db:seed --help для получения более подробной информации.

2) Вы можете создать таблицу вручную (которая имеет то же имя, что и таблица миграции, создаваемая в вашей БД) и вставить значения миграции, как это

insert into migrations(migration, batch) values('2015_12_08_134409_create_tables_script',1);

поэтому команда migrate не создаст таблицу, которая уже существует в таблица миграции.


если вы хотите просто опустить (но сохранить) миграцию и сеялку:

  1. переименуйте миграцию, удалив

из Laravel docs

по умолчанию команда db:seed запускает класс DatabaseSeeder, который может использоваться для вызова других классов seed. Однако вы можете использовать параметр --class, чтобы указать конкретный класс сеялки для запуска индивидуально

php artisan db:seed --class=UserTableSeeder

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

php artisan migrate --path=database/migrations/temp

просто комментарий к идее сеялка и - схемы. вот как я думаю

//$this->call(HvAccountsSeeder::class);

//Schema::create('users', function (Blueprint $table) {
          //  $table->increments('id');
          //  $table->string('name');
          //  $table->string('email')->unique();
          //  $table->string('password');
          //  $table->rememberToken();
           // $table->timestamps();
       // });
// Schema::drop('users');

чтобы напрямую ответить на ваш вопрос, Laravel не имеет способа сделать это в настоящее время.

Если я правильно вас понимаю, я предполагаю, что вы ищете способ временно отключить/пропустить определенный класс из DatabaseSeeder по умолчанию.

вы можете легко создайте свою собственную команду который примет строку, такую как имя модели/таблицы, и попытается запустить миграцию и семя для этой конкретной таблицы. Вам просто нужно что-то вроде следующий:

public function handle(){ //fire for Laravel 4.*

    $tables = explode(',', $this->option('tables'));//default []
    $skip = explode(',', $this->option('skip'));//default [] 
    $migrations = glob("*table*.php");//get all migrations
    foreach($migrations as $migrate){
        //if tables argument is set, check to see if part of tables
        //if file name not like any in skip.. you get the point