migrate コマンド — DBマイグレーションを未適用分から順に実行する

artisan
  • カテゴリ: artisan
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: php artisan migrate
  • 関連: migrate:rollback / migrate:refresh / migrate:fresh / migrate:status / make:migration
  • 変更履歴: (Laravel 11以降も継続利用。主な挙動に破壊的変更なし)

要点(TL;DR)

  • 未適用のマイグレーションを実行してスキーマを最新化するコマンド
  • 最低限の使い方:php artisan migrate
  • よくある罠:
    • 本番は --force 必須(対話なしで実行)
    • 大型DDLはロック・停止時間に注意(特にMySQL)
    • --path相対パス既定。絶対パスなら --realpath

概要

migratedatabase/migrations 以下(や指定パス)の未実行マイグレーションを順次実行します。環境差異をなくし、チーム・CI/CD・本番で同じ履歴を再現するための基礎コマンドです。実務ではデプロイ時に --force --no-interaction を併用し、障害時は migrate:rollback で直前バッチを戻します。

構文 / シグネチャ

php artisan migrate [--database=NAME] [--path=PATH] [--realpath] [--schema-path=FILE] \
  [--pretend] [--seed] [--seeder=CLASS] [--step] [--force]

引数(オプション)

オプション必須既定値説明
--databasestringいいえdefaultconfig/database.php の接続名を指定
--pathstringいいえなし実行対象マイグレーションの相対パス(例: database/migrations/subdir
--realpathboolいいえfalse--path絶対パスとして扱う
--schema-pathstringいいえなしスキーマダンプ(schema.sql)の読み込み元
--pretendboolいいえfalse実行せずSQLだけ表示
--seedboolいいえfalseマイグレーション完了後に db:seed も実行
--seederstringいいえDatabaseSeeder併用時に実行するシーダークラスを指定
--stepboolいいえfalse各ファイルを別バッチとして記録(ロールバック単位を細かく)
--forceboolいいえfalse本番など非対話環境で実行を許可

Artisan共通例:-n/--no-interaction(確認をすべてスキップ)、-q/--quiet など。

  • 戻り値:終了コード(成功 0、失敗 非0)
  • 例外/副作用:データベースDDL実行、migrations テーブルへのバッチ記録、--seed 併用時はDML実行

使用例

最小例

# デフォルト接続で未適用分を実行
php artisan migrate

実務例

# 例1:本番デプロイの安全セット(対話なし)
php artisan migrate --force --no-interaction --step

# 例2:特定接続(PostgreSQL)で、サブディレクトリだけ適用
php artisan migrate --database=pgsql --path=database/migrations/tenant

# 例3:挙動確認(SQLのみ出力)
php artisan migrate --pretend

よくある落とし穴・注意

  • 本番で --force 不足:CI/CDやSSH越しの実行は対話不可のため必須。
  • 大型DDLによるロック:MySQLのALTERはテーブルロック・暗黙コミットに注意。オンラインDDL(ALGORITHM=INPLACE など)検討や、段階的移行(カラム追加→並行書き込み→切替→旧カラム削除)を計画。
  • --path の解釈:既定はプロジェクトルートからの相対。絶対パスは --realpath を付与。
  • トランザクション差:PostgreSQLは多くのDDLがトランザクション対応。一方MySQLはDDLで自動コミットされるケースがあり、途中失敗で部分適用になることがある。
  • --step の使いどころ:粒度の細かいロールバックが必要な環境で有効(各ファイルが別バッチに)。

代替・関連APIとの比較

  • migrate:rollback:直近バッチを取り消し。小さく戻したいときは --step=N
  • migrate:refresh全ロールバック→再実行。データは保持されないことに注意。
  • migrate:fresh全テーブルDROP→全実行。開発用の一掃リセット向け。
  • migrate:status:適用状況の一覧。トラブル時のファイル漏れ確認に有用。
  • make:migration:定義ファイルを生成。実行は migrate が担当。

選定基準:本番は基本 migrate、障害切り戻しは rollback、ローカル初期化は fresh / refresh

テスト例(Pest)

<?php
use Illuminate\Support\Facades\Schema;

it('migrates successfully', function () {
    $this->artisan('migrate', ['--force' => true])->assertExitCode(0);

    expect(Schema::hasTable('migrations'))->toBeTrue();
});

トラブルシュート(エラー別)

症状/エラー原因対処
SQLSTATE[HY000] [1049] Unknown databaseDB名が存在しない/接続設定誤り.envDB_* を確認、DB作成後に再実行
Base table or view already exists既存テーブルと重複マイグレーションの前提を見直し、条件分岐(Schema::hasTable)や一度 rollback/fresh
Nothing to migrate.すべて適用済み新規ファイル名のタイムスタンプ・配置パスを確認
Class ... already exists / Class not foundクラス名とファイル名の不一致・重複マイグレーションクラス名をユニークに、オートロード再生成(composer dump-autoload
長時間固まる/タイムアウト大型DDLのロック・インデックス作成事前にオンラインDDL・分割適用、メンテナンス時間を確保

追加(artisanカテゴリの要件)

オプション表(要点)

オプション値の型既定値目的
--forceboolfalse非対話環境(本番/CI)で強制実行
--databasestringdefault接続名を切り替え
--pathstringなし特定ディレクトリ/ファイルのみ実行
--realpathboolfalse--path を絶対パスとして扱う
--schema-pathstringなしスキーマダンプの読込
--pretendboolfalse実行SQLの表示のみ
--seedboolfalse実行後にシーディング
--seederstringDatabaseSeeder実行するSeeder指定
--stepboolfalseロールバック単位をファイルごとに

実行環境

  • ローカル:検証や refresh/fresh が中心。
  • CI--force --no-interaction、接続は専用DB。
  • 本番:バックアップ・停止時間の計画、--force 必須、DDLの影響(ロック/レプリケーション)に留意。

副作用

  • スキーマ変更、migrations テーブル更新、--seed 併用時のデータ投入。

終了コード

  • 0: 成功(未適用なしでも成功)
  • >0: 失敗(例外・接続不可・SQLエラー等)

スケジューラ例(参考)

自動実行は推奨度低(デプロイパイプラインでの実行が無難)。検証用/単一ノード検証で使う例:

// app/Console/Kernel.php
protected function schedule(\Illuminate\Console\Scheduling\Schedule $schedule): void
{
    // 毎日3:00に検証用DBへ適用(例)
    $schedule->command('migrate --database=staging --force')
        ->dailyAt('03:00');
}

以上。実務では「デプロイの一部として migrate --force --no-interaction を実行、戻しは rollback --step」を定石にしてください。

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする