I've found that, while building up my database schema in Laravel, that failed migrations don't rollback, which kind of makes migrations pointless.
For example, I have this migration:
Schema::create('accounts', function(Blueprint $table)
{
$table->increments('act_id');
$table->string('act_name', 50)->unique();
$table->boolean('act_active')->default(1);
$table->unsignedInteger('act_type');
$table->unsignedInteger('act_businesstype')->default(1);
$table->timestamps();
});
Schema::table('accounts', function($table)
{
$table->foreign('act_businesstype')->references('bst_id')->on('businesstypes');
});
Anyway, if I run that migration, the table gets created just fine, but the foreign key fails and I get an error. That's fine. I should get an error. BUT, common sense has me assuming the following:
Okay, so
Am I doing something wrong here? The only way I've figured out how to "undo" a failed migration is to actually go into the database and drop the table. This is extremely frustrating when working on a complex schema where I'm going back and forth fixing errors.
So, I guess now that I've had my little rant, my question is:
How do I rollback a migration that throws an error?
One solution is to execute your migrations from within a transaction, so that if an error occurs mid-migration, nothing gets committed and the whole transaction gets rolled back. Antonio Carlos Ribeiro has written a great class that handles this process neatly; see his description of the process here as well as the finished migration class on GitHub.
Once you've installed his class, create your migrations so that they extend the new Migration class, and call migrateUp()
and migrateDown()
in place of up()
and down()
:
class CreateAccountsTable extends PragmaRX\Support\Migration {
protected function migrateUp()
...
...and enjoy not having to manually fix a botched migration again!
Coming back to this question years later and knowing much more about how databases work now:
There is no way for a migration to "automatically rollback". Schema changes cannot be performed in transactions. Only INSERTS, UPDATES, and DELETES can be rolled back.
In order for this to function correctly, there would need to be an equivalent "drop" script that runs in the event of an error to revert the schema change
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With