laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

migrate:fresh should drop tables in all databases #1026

Closed cweiske closed 6 years ago

cweiske commented 6 years ago

During development, artisan migrate:fresh is used to re-run all migrations on a clean database.

When using multiple databases, migrate:fresh fails for this use case because it only drops tables on the default database - see https://github.com/laravel/framework/issues/22681, https://github.com/laravel/framework/issues/21009 and https://github.com/laravel/framework/issues/21063

Please make artisan migrate:fresh drop the tables on all databases.

phroggyy commented 6 years ago

Just use the --database argument

cweiske commented 6 years ago

--database does not help because it drops the tables on one database (only one db name supported!) and then re-runs all migrations, which means migrations for all databases.

In the end, migrations are executed for all databases - and that will fail, because either A or B will still contain tables.

rs-sliske commented 6 years ago

allowing the database param to take multiple databases seems the most sensible way of doing this imo

personally i work on a few projects where not all the databases are managed from migrations in the laravel project (integrating with old systems which dont have (good) apis by reading directly from the database).

cweiske commented 6 years ago

My goal - as described as the use case above - would be to be able run migrate:fresh and be done with it.

If the --database parameter would support multiple databases, how does it then make sure that only the migrations for the listed databases are being run? That's the main problem IMO: Migrations being run on databases that have not been cleared.

mfn commented 6 years ago

I think this would require a slightly different default config/database.php.

With how things work right now, you you only have to adapt the mysql and/or the default and be done => it works.

If commands like migrate:fresh suddenly consider all defined in db.connections, it would easily break/confuse users experiences (assuming they didn't remove/disable the other defaults => which as of now isn't required).

saifulss commented 6 years ago

Perhaps let --database accept multiple databases, as was suggested above. Whatever UX issues there may be, it'll be understood that if the user passes that database value, he expects that database's tables to be dropped.

Then finally migrate:fresh can be useful for projects with multiple databases.

For now, I find myself having to make my own command to drop tables from multi-databases. Which feels meh cos I know migrate:fresh is so close to getting it done.

hailwood commented 6 years ago

Making migrate:fresh by default drop all databases will confuse users for the reasons stated by @mfn, and honestly feels like an exception rather than the most common use case.

Updating migrate:fresh --database to take multiple databases seems logical, we could also add a --all-databases/-a flag which would then run over all defined database connections.

dithidi commented 6 years ago

I'd like to request to reopen this. As recently I've entered into a project that requires multiple databases and being able to at least add multiple databases to the database flag would make the dev process much smoother.

drbyte commented 6 years ago

Perhaps use the proposed trait posted by @sepehr in the issue linked above: https://github.com/laravel/framework/issues/21063#issuecomment-360616841

ie: Battletest it in your own use, and then collaborate on a PR.

luizguilhermefr commented 6 years ago

A --all would be perfect. As stated by @cweiske using --database option is not suitable.

@taylorotwell would you reopen this?

ryanpaulfyfe commented 5 years ago

+1 for a re-open and consideration

JoelWigren commented 5 years ago

I have the same problem, even worse by using Lumen. I ended up writing my own command instead, pretty ruffly described: I peaked the command artisan:fresh thats is very well commented (thanks to author!), it can be found at vendor/illuminate/database/Console/MigrateCommand.php. As the comments points out the migrate:fresh only calls other "migrate" commands and then seeder if needed. So I created my own command as docs describe https://laravel.com/docs/5.8/artisan. In my command I used config('database.connections') to get all the connections and created a loop. public function handle() { $servers = config('database.connections'); foreach($servers as $server => $config) { if ($server == 'server') { continue; } config(['database.default' => $server]); $this->call('migrate:fresh'); } }

And as you guys can see I filter out connections not used by tenats, go easy on the namnig. This is my "test out" application where I am trying to work out the hard parts :) There will be an issue when creating migrations for tables not used by tenats but only "badly named server connection", this can be fixed by wrapping the Schema::create with

if (! Schema::connection('server')->hasTable('clients')) { Schema::create(...}

Hopefully this will help someone! And yes, my command was named migrate:all

luizguilhermefr commented 4 years ago

It's awful how Laravel still doesn't have this.

gabrieldarruspe commented 4 years ago

As a workaround, this did the trick for me: php artisan db:wipe --database ConnectionA php artisan migrate:fresh --database ConnectionB