2

I have a custom console command that needs to loop through some companies and make a database for each. The command works now, but only once. It does not run the migration the second time around in the loop. So basically if I have 2 blank DBs (db_one and db_two) the config runs and migrates the first time for db_one and when the loop runs again, nothing happens to db_two. If I replace the console command to just echo out the DB name it returns both so I know its not the loop. Also if I log out the db used in each connection of the loop, its the correct DB.

Here is the command:

public function handle()
{
    $companies = Company::all();

    foreach( $companies as $company)
    {
        \Config::set('database.connections.company.database', $company->db_name);

        Artisan::call( 'migrate', [
            '--database' => 'company',
            '--path' => 'database/migrations/company',
        ]);

        $this->info(  config('database.connections.company.database') );

    }
}

log error:

local.ERROR: Database [10_barrel] not configured. {"userId":1,"email":"packy@sites.com","exception":"[object] (InvalidArgumentException(code: 0): Database [db_2] not configured. at /Users/Sites/cheers/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:140)

database.php

'connections' => [

        'main' => [
            'driver' => 'mysql',
            'host' => env('MAIN_DB_HOST', '127.0.0.1'),
            'port' => env('MAIN_DB_PORT', '3306'),
            'database' => env('MAIN_DB_DATABASE', 'forge'),
            'username' => env('MAIN_DB_USERNAME', 'forge'),
            'password' => env('MAIN_DB_PASSWORD', ''),
            'unix_socket' => env('MAIN_DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

        'company' => [
            'driver' => 'mysql',
            'host' => env('COMPANY_DB_HOST', '127.0.0.1'),
            'port' => env('COMPANY_DB_PORT', '3306'),
            'database' => '',
            'username' => env('COMPANY_DB_USERNAME'),
            'password' => env('COMPANY_DB_PASSWORD'),
            'unix_socket' => env('COMPANY_DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
]

env:

COMPANY_DB_HOST=127.0.0.1
COMPANY_DB_PORT=3306
COMPANY_DB_USERNAME=root
COMPANY_DB_PASSWORD=
Packy
  • 3,405
  • 9
  • 50
  • 87

2 Answers2

0

I assume that you have some problem with your logic. You set a DB name to your configuration but dose this DB exit? And what about the rest? User, Password? Are they always the same?

The Loop is not the problem, right! $companies = Company::all(); Will get get the date from the default database, and you can loop.

I assume the first DB in your list exist already (mayby the default one), but the second on not, and migrate do not create a database it only fills it with data, if laravel can connect to th DB.

Webdesigner
  • 1,954
  • 1
  • 9
  • 16
0

It was quite interesting. I need to say I wasn't able to fully reproduce your error (I didn't get any error in log) but for sure migration is run only for 1st loop iteration.

First thing instead of:

Artisan::call

I would recommend you to use:

$this->call

you will get extra output what is really going.

But the most important thing to make it work is to disconnect from database and purging the connection. Otherwise Laravel won't see that you changed your database name in configuration and will use old database.

So you should add:

$this->laravel['db']->purge('company');

at the end of loop to make it possible to run migrations like this.

I've tested it and it's working for me without any problem.

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291