framework: Running seed for another connection won't work with dynamic config
Hi,
I have a unusual case with seeding my database. I’m aware that I can run the seed using the following command (within a custom command class)
$this->call('db:seed', [
'--class' => 'TenantDatabaseSeeder',
'--database' => 'tenant',
]);
However I need to set the config for the database dynamically since each tenant user has its’ own database. So I can simply set the database like so
$config = Config::get('database.connections.tenant');
$config['database'] = $tenant->database_name;
$config['username'] = $tenant->database_username;
$config['password'] = $tenant->database_password;
Config::set('database.connections.tenant', $config);
Config::set('database.default', 'tenant');
This works perfectly fine for setting the correct database connection for the application. It goes wrong at the point that the db:seed
command is fired. It seems like it’s setting up a new application instance and therefor it resets the database config as well.
So this is my code for the current command I’m running.
$this->setDatabaseConfig($tenant);
$this->call('db:seed', [
'--class' => 'TenantDatabaseSeeder',
'--database' => 'tenant',
]);
Any help would be appreciated. Thanks in advance.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 25 (23 by maintainers)
I appreciate that usually this sort of thing is more suited to the forums, but I done an awful lot of research regarding this exact problem, and I’ve not yet come across a multi-tenant multi-database solution that doesn’t involve setting the tenant database config at runtime. I’m certain if I asked on the forums the answer I get would be to dynamically set the config at run time, either myself or by using a library.
For example, these packages all dynamically set the database config in one way or another at runtime:
I am, and I’m sure others would be, incredibly curious as to see what your clean solution to this was that avoided having to set config at runtime.
Yep that’s fine for a small number of tenants. However our app has close to 300 tenants, each with their own database. I don’t want to add 300 different database connections to the database config file. Additional tenants are added all the time, and having to add the make commits to add the additional database connections would be annoying.
So I found a way to solve this. I can simply call
DB::reconnect('tenant');
afterI have set the config. This way the new config is applied to the new database connection.The problem occurred when there was already a call to the database before the config was set. So you would get the same class instance, with the already applied settings.
Thanks all for thinking with me!
@GrahamCampbell It would still be nice too see an example solution from you 😉
@GrahamCampbell It would be nice if you could provide a small example on the subject 😄
You shouldn’t be doing that. You need to instead setup multiple database connections.
As the developer of
orchestra/tenanti
, this argument is true.This is also true. However, we setup unique custom database connection at runtime (not replacing a template such as
database.connections.tenant
). As an example, if the template isdatabase.connections.tenant
, then the actual connection for users with id=1 isdatabase.connections.tenant_1
.Not a bug. I think you’ve got the idea of the config incorrect. We read it once at boot, and that’s it. Any modifications you make will be ignored.