spatie/laravel-migrate-fresh
Adds a migrate:fresh Artisan command to drop all database tables and rebuild from migrations, even if you don’t implement down() methods. Supports MySQL, SQLite, PostgreSQL, and SQL Server. (Built into Laravel 5.5+)
Installation:
composer require spatie/laravel-migrate-fresh
(Note: Since Laravel 5.5+, this is built into core as migrate:fresh. This package is a legacy wrapper for older versions.)
First Use Case: Run the command to wipe and rebuild the database from scratch:
php artisan migrate:fresh
--seed to populate fresh data:
php artisan migrate:fresh --seed
Where to Look First:
CI/CD Workflows:
# Example GitHub Actions step
- name: Reset DB
run: php artisan migrate:fresh --env=testing
Testing:
migrate:refresh for large apps):
// In phpunit.xml
<env name="DB_CONNECTION" value="sqlite_testing"/>
<env name="DB_DATABASE" value=":memory:"/>
php artisan migrate:fresh --env=testing
Integration with Factories/Seeders:
db:seed for reproducible test environments:
php artisan migrate:fresh --seed --class=TestDatabaseSeeder
Environment-Specific Flags:
--env to target specific .env files (e.g., staging, production):
php artisan migrate:fresh --env=staging
Pre-Migration Hooks:
// app/Console/Kernel.php
protected $commands = [
\Spatie\MigrateFresh\Console\MigrateFreshCommand::class,
\App\Console\Commands\BackupBeforeFresh::class,
];
Post-Migration Tasks:
--execute to run arbitrary commands after migration:
php artisan migrate:fresh --execute="php artisan optimize:clear"
migrate:fresh executions in the "Commands" tab for debugging.No Rollback Safety:
migrate:refresh, migrate:fresh drops all tables unconditionally. Ensure:
--execute to archive data first).ON DELETE CASCADE or manual cleanup.Seed Order Dependencies:
migrate:fresh may fail if models rely on each other. Use explicit seeders:
php artisan db:seed --class=UsersTableSeeder --class=PostsTableSeeder
Schema Changes in Production:
migrate:fresh in production unless absolutely necessary (e.g., catastrophic corruption). Use migrate or migrate:refresh instead.Legacy Package Note:
migrate:fresh command instead.Failed Migrations:
migrations table for stuck migrations:
SELECT * FROM migrations WHERE batch = (SELECT MAX(batch) FROM migrations);
migrate:fresh.Permission Errors:
DROP privileges:
GRANT DROP ON *.* TO 'laravel_user'@'%';
Custom Database Connections:
--database:
php artisan migrate:fresh --database=mysql_secondary
Soft Deletes:
migrate:fresh does not handle soft deletes. Use Model::query()->forceDelete() in seeders if needed.Custom Command Logic:
php artisan vendor:publish --tag=migrate-fresh
handle() in app/Console/Commands/MigrateFresh.php.Pre/Post Hooks:
// In EventServiceProvider
protected $listen = [
'migrate.fresh.starting' => [
\App\Listeners\BackupDatabase::class,
],
];
Conditional Execution:
migrate:fresh if the database is empty (e.g., in CI):
if [ -z "$(php artisan db:table --name=migrations | tail -n +2)" ]; then
php artisan migrate:fresh
fi
How can I help you explore Laravel packages today?