I work in a project that uses multiple databases. It seems like Laravel only uses the migrations-table in the database that is set as default. I would like one migrations table per database that logs the migrations that have been done to that specific database. Is this possible?
I have defined the databases in the config like this:
'connections' => [
'db1' => array(
'driver' => 'mysql',
'host' => 'db1.host',
'database' => 'db1',
'username' => 'username',
'password' => 'password',
),
'db2' => [
'driver' => 'mysql',
'host' => 'db2.host',
'database' => 'db2',
'username' => 'username',
'password' => 'password',
]
],
I also made the first database (db1) the default one
'default' => 'db1'
I install the migrations table on both databases
artisan migrate:install --database=db1
artisan migrate:install --database=db2
After that i proceed to create a couple of database specifc migrations
Create table test1 in db1 database:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTest1Table extends Migration
{
public function up()
{
Schema::connection('db1')->create('test1', function(Blueprint $table)
{
$table->increments('id')->unsigned();
});
}
public function down()
{
Schema::connection('db1')->drop('test1');
}
}
Create table test2 in db2 database:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTest2Table extends Migration
{
public function up()
{
Schema::connection('db2')->create('test2', function(Blueprint $table)
{
$table->increments('id')->unsigned();
});
}
public function down()
{
Schema::connection('db2')->drop('test2');
}
}
I now run the migrations
artisan migrate
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
| create_test1_table_in_db1 | 1 |
+-----------------------------+-------+
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
| create_test2_table_in_db2 | 1 |
+-----------------------------+-------+
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
| create_test1_table_in_db1 | 1 |
| create_test2_table_in_db2 | 1 |
+-----------------------------+-------+
+-----------------------------+-------+
| migration | batch |
+-----------------------------+-------+
Empty set
To run the specific migration in Laravel, you need to use --path option with the php artisan migrate command. Let's take a simple example, we have '2019_12_04_131405_create_payments_table. php' migration in the database/migrations directory and we would like to run this migration.
When you run artisan migrate then it will only run migrations that haven't already been applied unless you use migrate:refresh in which case it will reset and re-run all migrations.
Article on usage of multiple database usage in Laravel - https://stackcoder.in/posts/laravel-7x-multiple-database-connections-migrations-relationships-querying
Use the --database
parameter with the migrate
command and store the migrations for each database in separate directories.
You could have separate directories in app/database/migrations
for each of your database (in your case db1
and db2
) and store the appropriate migrations in each directory. Then you could run the migrations like this:
artisan migrate --database="db1" --path="app/database/migrations/db1"
artisan migrate --database="db2" --path="app/database/migrations/db2"
This way your migrations
table will be independent for each database.
If you want to go the extra mile and automate the process you could create your custom command that will run all the migrations at once. You can create the command like this (use make:console
for Laravel 5.0 up to 5.2 or make:command
for Laravel 5.2+):
artisan command:make MigrateAllCommand --command=migrate:all
This will create a new file app/commands/MigrateAllCommand.php
. Your command's fire
method would look something like this:
public function fire()
{
foreach (Config::get('database.connections') as $name => $details)
{
$this->info('Running migration for "' . $name . '"');
$this->call('migrate', array('--database' => $name, '--path' => 'app/database/migrations/' . $name));
}
}
This will work provided the name of the database configuration key is the same as the migration directory name. You can then just call it like this:
artisan migrate:all
You can check the Laravel Command Docs for more info.
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