web-dev-qa-db-ja.com

特定のLaravel移行を1つ実行する(単一ファイル)

laravel 4.ですべての未処理の移行を実行したくありません。4つの移行があります。ここで、1つの移行を実行したいだけです。代わりに:php artisan migrate私は次のような特定の移行を実行したいと思います:php artisan migrate MY_MIGRATION_TO_RUN

58
Mamadou

間違っているようです。

移行はLaravelによって1つずつ実行され、作成された正確な順序でなので、実行と実行の順序を追跡できます。そうすることで、Laravelは、データベースを壊すリスクなしに、移行のバッチを安全にロールバックできます。

ユーザーに手動で実行する権限を与えると、データベースの変更をロールバックする方法を(確実に)知ることができなくなります。

データベースで何かを実行する必要がある場合は、DDLスクリプトを作成して、Webサーバーで手動で実行することをお勧めします。

または、新しい移行を作成し、職人を使用して実行します。

編集:

最初に実行する必要がある場合は、最初に作成する必要があります。

並べ替えるだけの場合は、ファイルの名前を最初に変更します。移行はtimestempで作成されます:

2013_01_20_221554_table

この移行の前に新しい移行を作成するには、名前を付けることができます

2013_01_19_221554_myFirstMigration

実行済みの移行をapp/config/database/migrations /フォルダーから移動するだけです。次に、コマンドphp artisan migrateを実行します。私にとって魅力のように働いた。

37

マイグレーションをより多くのフォルダーに入れて、次のようなものを実行できます。

php artisan migrate --path=/app/database/migrations/my_migrations
24
fico7489

Laravel 4マイグレーションphp artisan migrate --pretendを実行する際の不安を和らげる素敵な小さなスニペット。これにより、実際の移行を実行した場合に実行されるSQLのみが出力されます。

最初の4つの移行は既に実行されているようです。 php artisan migrateを実行すると、新しい、最近の移行のみが実行されると思います。

アドバイス:すべてのup()およびdown()が期待どおりに動作することを確認します。私は、移行を実行するときにup()、down()、up()を実行するのが好きです。 5-6の移行を取得し、down()とup()を100%一致させなかったため、手間をかけずにロールバックできないことに気付くのは恐ろしいことです =

ちょうど私の2セント! --pretendが役立つことを願っています。

22
Erik Aybar

移行を再実行する唯一の方法は、ダーティな方法です。データベースを開き、移行を表す移行テーブルの行を削除する必要があります。

次に、php artisan migrateを再度実行します。

15
elfif

次のように、ターミナルから移行用に別のディレクトリを作成できます。

mkdir /database/migrations/my_migrations

次に、実行する特定の移行をそのディレクトリに移動し、次のコマンドを実行します。

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

お役に立てれば!

4
jidesakin

私は別の投稿でこの答えをしましたが、これを行うことができます:artisan migrateを実行してすべての移行を実行し、次のSQLコマンドで移行テーブルを更新し、移行が1つずつ実行されているように見せます:

SET @a = 0;  
UPDATE migrations SET batch = @a:=@a+1;

特定の移行にのみ影響を与える場合は、バッチ列を1、2、3、4などに変更します。そこにWHERE batch>=...条件を追加(および@aの初期値を更新)します。

この後、必要なだけartisan migrate:rollbackすることができ、移行を1つずつ実行します。

3
Colin

ローカルホストでのみ利用できるようにする簡単な方法が1つあります

  1. 変更必要に応じて移行ファイル
  2. phpMyAdminまたはデータベーステーブルを表示するために使用するものを開きます
  3. 目的のテーブルを見つけてドロップします
  4. 移行テーブルを見つけて開きます
  5. このテーブルの移行フィールドの下で、目的のテーブル名を見つけてその行を削除します
  6. 最後に、コマンドラインまたは端末からコマンドphp artisan migrateを実行します。これにより、データベースの移行テーブルに存在しないテーブルのみが移行されます。

この方法は完全に安全であり、非専門的な方法のように見えてもエラーや問題は発生しませんが、完全に機能します。

幸運を

2
Ahmed Mabrouk

移行を適用したくない場合は、移行に例外をスローすると、移行プロセス全体が停止します。

このアプローチを使用すると、一連の移行を複数のステップに分割できます。

1

最新の移行ファイルを実行する場合は、次を実行します。

php artisan migrate

移行を追加する前に戻すこともできます:

php artisan migrate: rollback
1
Jammer

同じ問題があります。次のような最初の移行ファイルにテーブル作成コードをコピーします。

  public function up()
    {
        Schema::create('posts', function(Blueprint $table){
            $table->increments('id');
            // Other columns...
            $table->timestamps();
        });
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            // Other columns...
            $table->softDeletes()->nullable();
        });
    }

また、batchテーブルのmigrations列番号を変更(減少)できます;)

そして、php artisan migrateを実行します。

1
ivahidmontazer

テスト目的のみの場合、これは私がそれを行う方法です:

私の場合、いくつかの移行があり、そのうちの1つにはApp-Settingsが含まれています。

私はアプリをテストしていますが、すべての移行が既にセットアップされているわけではありませんが、新しいフォルダー「将来」に移動するだけです。このフォルダには職人は手を加えず、必要な移行のみを実行します。

ダーティな回避策ですが、動作します...

1
Jan Schuermann

これにまだ興味がある人のために、Laravel 5 update:Laravelは、一度に1つの移行ファイルを実行するオプションを実装しました(バージョン5.7 )。

これを実行できます:php artisan migrate --path=/database/migrations/my_migration.php(回答済み ここ

Illuminate\Database\Migrations\Migrator::getMigrationFiles()には次のコードが含まれているためです:return Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php');ソースコードを参照)


しかし、私のユースケースでは、実際には、1つだけではなくすべてのマイグレーションを同時に実行することを望んでいました

そこで私はLaravelの方法でMigratorの異なる実装を登録し、使用するファイルを決定します。

/**
 * A migrator that can run multiple specifically chosen migrations.
 */
class MigrationsSetEnabledMigrator extends Migrator
{
    /**
     * @param Migrator $migrator
     */
    public function __construct(Migrator $migrator)
    {
        parent::__construct($migrator->repository, $migrator->resolver, $migrator->files);

        // Compatibility with versions >= 5.8
        if (isset($migrator->events)) {
            $this->events = $migrator->events;
        }
    }

    /**
     * Get all of the migration files in a given path.
     *
     * @param  string|array $paths
     * @return array
     */
    public function getMigrationFiles($paths)
    {
        return Collection::make($paths)->flatMap(function ($path) {
            return Str::endsWith($path, ']') ? $this->parseArrayOfPaths($path) :
                (Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path . '/*_*.php'));
        })->filter()->sortBy(function ($file) {
            return $this->getMigrationName($file);
        })->values()->keyBy(function ($file) {
            return $this->getMigrationName($file);
        })->all();
    }

    public function parseArrayOfPaths($path)
    {
        $prefix = explode('[', $path)[0];
        $filePaths = explode('[', $path)[1];
        $filePaths = rtrim($filePaths, ']');

        return Collection::make(explode(',', $filePaths))->map(function ($filePath) use ($prefix) {
            return $prefix . $filePath;
        })->all();
    }
}

'migrator'としてコンテナに登録する必要があります($app['migrator']としてアクセスできるようにするため)。これは、MigrateコマンドがIoCに登録されているときにMigrateコマンドがアクセスする方法です。そのために、このコードをサービスプロバイダーに配置します(私の場合、DatabaseServiceProviderです)。

    public function register()
    {
        $this->app->extend('migrator', function ($migrator, $app) {
            return new MultipleSpecificMigrationsEnabledMigrator($migrator);
        });

        // We reset the command.migrate bind, which uses the migrator - to 
        // force refresh of the migrator instance.
        $this->app->instance('command.migrate', null);
    }

次に、これを実行できます。

php artisan migrate --path=[database/migrations/my_migration.php,database/migrations/another_migration.php]

カンマで区切られた複数の移行ファイルに注意してください。

Laravel 5.4でテストおよび動作しており、Laravel 5.8と互換性があります。

なぜ?

興味のある方へ:ユースケースはデータとともにデータベースのバージョンを更新するです。

たとえば、すべてのユーザーの番地と番地を新しい列にマージしたいと考えた場合、street_and_houseと呼びましょう。そして、安全でテストされた方法で複数のインストールでそれをしたいと想像してください-あなたはおそらくそのためのスクリプトを作成するでしょう(私の場合、私はデータバージョン管理コマンド-職人コマンドを作成します)。

このような操作を行うには、まずユーザーをメモリにロードする必要があります。次に、移行を実行して古い列を削除し、新しい列を追加します。次に、各ユーザーにstreet_and_house=$street . " " . $house_noを割り当ててユーザーを保存します。 (ここでは簡略化していますが、他のシナリオを確実に想像できます)

そして、いつでもすべての移行を実行できるという事実に依存したくありません。たとえば、1.0.0から1.2.0に更新し、そのような更新のバッチが複数あったとします。それ以上の移行を実行すると、データが破損する可能性があります。これらの移行は専用の更新コマンドで処理する必要があるためですしたがって、この更新プログラムでの操作方法がわかっている選択した既知の移行のみを実行し、データに対して操作を実行し、次のデータ更新コマンドを実行する可能性があります。 (可能な限り防御的になりたい)。

これを実現するには、前述のメカニズムが必要であり、このようなコマンドが機能するために実行する移行の固定セットを定義します。

注:マジック__callメソッドを利用する単純なデコレーターを使用して、継承を回避することをお勧めします(Laravelが\Illuminate\Database\Eloquent\Builderで使用する同様のメカニズム\Illuminate\Database\Query\Builder)、しかしMigrateCommandは、悲しいことに、そのコンストラクタにMigratorのインスタンスが必要です。


最後のメモ:質問へのこの回答を投稿したかった laravelで特定の移行を実行する方法 、それはLaravel 5-特定です。しかし、私はできません-その質問はこの質問の複製としてマークされているためです(ただし、この質問にはLaravel 4のタグが付けられています)。

0
Jan Bradáč

これは私が使用する悪いアプローチです。移行したい特定のファイルを除く他の移行ファイルを削除し、移行完了後にPHP artisan migrateを実行しますごみ箱に移動して復元します削除されたファイル

0
israelnojr

行1でreturnを使用したため、以前のデータベースはそのまま保持されます。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        return;  // This Line
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 50);
            $table->string('slug', 50)->unique();
            $table->integer('role_id')->default(1);
            $table->string('email', 50)->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('mobile', 10)->unique();
            $table->timestamp('mobile_verified_at')->nullable();
            $table->text('password');
            $table->integer('can_login')->default(1);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        return;// This Line
        Schema::dropIfExists('users');
    }
}

とても簡単...!移行フォルダに移動するだけです。すべての移行ファイルを別のフォルダーに移動します。次に、すべての移行を1つずつ移行フォルダーに戻し、そのうちの1つに対して移行を実行します(php artisan)。不正な移行ファイルをマスター移行フォルダーに挿入し、コマンドでphp artisan migrateを実行すると、プロンプトがエラーになります。

0
musllim boy

以下のソリューションを使用できます:

  1. 移行を作成します。
  2. php artisan migrate:statusなどの移行ステータスを確認してください。
  3. 新しい移行のフルネームをコピーして、php artisan migrate:rollback --path:2018_07_13_070910_table_testsのようにします。
  4. そして、これをphp artisan migrateします。

最後に、特定のテーブルを移行します。幸運を。