abbassiddiqi's avatar

How to force `artisan migrate:fresh` to only delete tables with the prefix set for the application

I have multiple lumen applications connected to the same single database. And every lumen application has prefix for the database tables using environment variable DB_PREFIX=my_prefix_.

Right now when I do php artisan migrate:fresh, it deletes all the tables from the database. Even if they are generated by other lumen application, and have a different prefix. They all get deleted.

What I have

  • single database
  • multiple lumen applications connected to that single database

What I want

  • Any solution to block artisan migrate:fresh command, so that no one accidentally deletes the whole database
  • Or a solution to force artisan migrate:fresh command to only delete tables with the prefix defined for the application.

Any help / suggestions will be appreciated.

0 likes
8 replies
Cronix's avatar

simply use migrage:refresh command instead of migrate:fresh.

As the docs mention, using fresh drops all tables in the db. It doesn't use the down() methods of your migrations.

refresh will only roll back the actual migrations by actually running the down() methods on all of your migrations, and then migrating from scratch.

https://laravel.com/docs/5.7/migrations#rolling-back-migrations

1 like
wilburpowery's avatar

the migrate:fresh command will show a alert if you try running it in a production environment. So that could help with the 1st thing.

For the second option, you might consider replacing themigrate:fresh command class in each of your application. That way you could set it to only drop tables with a given prefix.

abbassiddiqi's avatar

Thanks @Cronix for your quick answer.

Yes I know the migrate:refresh will rollback the listed migrations for the particular application, and run the up() functions.

But my problem lies somewhere else.

My problem

I just want to block the migration:fresh command, so no other developer accidentally runs that command. Because if someone runs that command, there is no going back.

So what I want is, if someone tries to run artisan migrate:fresh it should say this command is blocked, or restricted. This command can provide more harm than good for my use case. I just want to restrict/block this command.

Cronix's avatar

I don't know if this is the best solution, but it works.

First, make a new command (just copy/paste this). Use this to extend the original FreshCommand and give it the same signature.

/app/Console/Commands/RemoveMigrateFresh.php.

<?php

namespace App\Console\Commands;

use Illuminate\Database\Console\Migrations\FreshCommand as MigrateFreshCommand;

class RemoveMigrateFresh extends MigrateFreshCommand
{

    protected $signature = 'migrate:fresh';

    protected $description = 'This command has been disabled.';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $this->error('migrate:fresh has been disabled!');
    }
}

Then, in app/Providers/AppServiceProvider, add this to the register() method.

public function register()
{
    $this->app->singleton(
        'Illuminate\Database\Console\Migrations\FreshCommand',
        'App\Console\Commands\RemoveMigrateFresh'
    );
}

The command will still be listed when you do php artisan, but have the new description

migrate:fresh        This command has been disabled.

And when you execute php artisan migrate:fresh, it doesn't do anything (no tables dropped). All it does is output

migrate:fresh has been disabled!

Edit: crap, just realized this was in the Lumen section. I hope this works there too as I haven't tried in Lumen.

1 like
abbassiddiqi's avatar

That is an awesome solution. I tried that in lumen, it did not overridden the original command. So it did not worked for me yet.

If it works, that would be perfect solution for me.

Can you double check why it did not worked for lumen, I followed the exact code?

Cronix's avatar

Sorry, I don't use lumen. I didn't even notice this was in the Lumen section until after I posted that. I'm sorry about that.

Please or to participate in this conversation.