Seeder runs fine the first time but does not do so

2019-02-27 07:57发布

问题:

I am working on a multi tenant multi database application where I have a main DB which consists of a tenant table and then for each tenant that is created, there is a new DB created. I am writing a seed file for this and I am running it 3 times to create 3 Tenants and subsequent 3 DB's for them.

It runs fine the first time. A new tenant is created in the main DB. A new DB is created using the username of the new tenant. The DB is also migrated with the Artisan command call from the code. But in the next 2 loops, the tenants are created in the main DB and new DB's are also created for them but the Artisan command call does not migrate the DB's.

public function run()
{
    $faker = Faker::create();

    // Fetching all tenants
    $tenants = App\Tenant::all();

    // Deleting their databases
    $tenants->each(function($tenant){
        DB::statement('DROP DATABASE IF EXISTS ' . $tenant->username);
    });

    // Truncating the tenants table itself
    DB::table('tenant')->truncate();

    for($i = 0; $i < 3; $i++){

        $company = $faker->company();
        $description = $faker->text();
        $logo = $faker->imageUrl(50, 50);
        $username = str_random(8);

        \Config::set('database.default', 'archive');

        echo 'Creating tenant ' . $i . "\r\n";

        Tenant::create([
            'name'          => $company,
            'description'   => $description,
            'logo'          => $logo,
            'username'      => $username,
        ]);

        DB::statement('CREATE DATABASE ' . $username);

        \Config::set('database.connections.tenant.database', $username);
        \Config::set('database.default', 'tenant');

        echo 'Migrating tenant ' . $i . "\r\n";

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

        echo "\r\n";
    }
}

What am I doing wrong here. It runs perfectly the first time. And then the last two times only the DB's are created but are not migrated. Only the first DB is migrated successfully from this. And no error is thrown from artisan.

The command line output is as follows:

Creating tenant 0

Migrating tenant 0


Creating tenant 1

Migrating tenant 1


Creating tenant 2

Migrating tenant 2

回答1:

The database connection is kept alive in Laravel, which means that it will not switch to new database when you change the database name via config. You need to force the background connection to be reconnected by DB::connection($connection)->reconnect().

When running migrations, because Laravel use the database name and the table name to check the existence of the migrations table, you need to update the table name of the current connection as well.

In your case:

# ...
\Config::set('database.connections.tenant.database', $username);
\Config::set('database.default', 'tenant');

\DB::reconnect();
\DB::setDatabaseName($username);
# ...