- カテゴリ: 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
- 本番は
概要
migrate は database/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]
引数(オプション)
| オプション | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
--database | string | いいえ | default | config/database.php の接続名を指定 |
--path | string | いいえ | なし | 実行対象マイグレーションの相対パス(例: database/migrations/subdir) |
--realpath | bool | いいえ | false | --path を絶対パスとして扱う |
--schema-path | string | いいえ | なし | スキーマダンプ(schema.sql)の読み込み元 |
--pretend | bool | いいえ | false | 実行せずSQLだけ表示 |
--seed | bool | いいえ | false | マイグレーション完了後に db:seed も実行 |
--seeder | string | いいえ | DatabaseSeeder | 併用時に実行するシーダークラスを指定 |
--step | bool | いいえ | false | 各ファイルを別バッチとして記録(ロールバック単位を細かく) |
--force | bool | いいえ | 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 database | DB名が存在しない/接続設定誤り | .env の DB_* を確認、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カテゴリの要件)
オプション表(要点)
| オプション | 値の型 | 既定値 | 目的 |
|---|---|---|---|
--force | bool | false | 非対話環境(本番/CI)で強制実行 |
--database | string | default | 接続名を切り替え |
--path | string | なし | 特定ディレクトリ/ファイルのみ実行 |
--realpath | bool | false | --path を絶対パスとして扱う |
--schema-path | string | なし | スキーマダンプの読込 |
--pretend | bool | false | 実行SQLの表示のみ |
--seed | bool | false | 実行後にシーディング |
--seeder | string | DatabaseSeeder | 実行するSeeder指定 |
--step | bool | false | ロールバック単位をファイルごとに |
実行環境
- ローカル:検証や
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」を定石にしてください。

