Dans mon application, chaque utilisateur a sa propre base de données créée lors de son inscription. Les données de connexion et de base de données (nom de la base de données, nom d'utilisateur, mot de passe) sont enregistrées dans une table dans la base de données par défaut.
try{
DB::transaction(function() {
$website = new Website();
$website->user_id = Auth::get()->id;
$website->save();
$database_name = 'website_'.$website->id;
DB::statement(DB::raw('CREATE DATABASE ' . $database_name));
$websiteDatabase = new WebsiteDatabase();
$websiteDatabase->website_id = $website->id;
$websiteDatabase->database_name = $database_name;
$websiteDatabase->save();
});
} catch(\Exception $e) {
echo $e->getMessage();
}
Maintenant, je veux exécuter quelques migrations sur la base de données d'un nouvel utilisateur après sa création.
C'est possible?
merci
Dans votre app/config/database.php, vous devez:
<?php
return array(
'default' => 'mysql',
'connections' => array(
# Our primary database connection
'mysql' => array(
'driver' => 'mysql',
'Host' => 'Host1',
'database' => 'database1',
'username' => 'user1',
'password' => 'pass1'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Our secondary database connection
'mysql2' => array(
'driver' => 'mysql',
'Host' => 'Host2',
'database' => 'database2',
'username' => 'user2',
'password' => 'pass2'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);
Maintenant que vous avez préparé deux connexions à la base de données dans votre migration, vous pouvez effectuer:
Schema::connection('mysql2')->create('some_table', function($table)
{
$table->increments('id');
});
Cela devrait fonctionner. Plus d'infos sur: http://fideloper.com/laravel-multiple-database-connections
Si vous placez la configuration de la base de données sur le database.php
fichier, cela peut vous aider:
php artisan migrate --database=**otherDatabase**
J'ai en fait rencontré le même problème et la réponse de Joe n'a pas fonctionné dans mon cas, car j'ai différentes connexions à la base de données (donc hôte, port, utilisateur et passe différents).
Par conséquent, la migration doit effectuer de nombreuses reconnexions tout le temps:
migrations
et clients
Et puis bouclez-le pour chaque client.
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$defaultConnection = BackendConfig::getDatabaseConfigArray();
$clients = ClientController::returnDatabasesForArtisan();
foreach ($clients as $client) {
BackendConfig::setDatabaseFromClient($client);
Schema::create('newtable', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->timestamps();
});
BackendConfig::setDatabaseFromArray($defaultConnection);
}
}
Et la classe où la magie est stockée:
class BackendConfig
{
public static function getDatabaseConfigArray($client_id = 1)
{
$connection = config('database.default');
return [
'id' => $client_id,
'Host' => config("database.connections.$connection.Host"),
'port' => config("database.connections.$connection.port"),
'username' => config("database.connections.$connection.username"),
'password' => config("database.connections.$connection.password"),
];
}
public static function setDatabaseFromArray($array)
{
self::setDatabase($array['id'], $array['Host'], $array['port'], $array['username'], $array['password'], true);
DB::disconnect();
}
public static function setDatabaseFromClient(Client $client)
{
DB::disconnect();
self::setDatabase($client->id, $client->database->Host, $client->database->port, $client->database->username, $client->database->password, true);
}
public static function setDatabase($client_id, $Host, $port, $username, $password)
{
$connection = config('database.default');
$database_name = $connection . '_' . $client_id;
config([
"database.connections.$connection.database" => $database_name,
"database.connections.$connection.Host" => $Host,
"database.connections.$connection.port" => $port,
"database.connections.$connection.username" => $username,
"database.connections.$connection.password" => $password,
]);
}
Avec cette solution, je peux exécuter exactement les mêmes migrations sur chaque client, mais la migration est simplement stockée dans client_1, mon type de client maître.
Attention toutefois aux deux DB::disconnect();
. Cela va gâcher la situation sans ceux-ci car les journaux de migration sont stockés dans la base de données d'un autre client ou autre.
Ah et au fait, ClientController ne fait rien de spécial:
public static function returnDatabasesForArtisan()
{
return Client::select('*')->with('database')->get();
}
J'ai le même problème, ma solution est de changer la base de données en utilisant Config::set
Puis d'exécuter Artisan::call("migrate")
. en fonction de votre code:
DB::statement(DB::raw('CREATE DATABASE ' . $database_name));
Config::set('database.connections.mysql.database', $database_name);
Artisan::call("migrate --database=mysql");
la configuration n'a changé que sur votre session, puis réinitialisée plus tard en tant que paramètre actuel.
La meilleure solution est que vous pouvez appeler cette méthode sur AppServiceProvide
c'est la meilleure solution pour ce type de problème. J'utilise ceci dans mon projet. Dans mon cas, j'ai deux environnements Développement et Production. donc lorsque le projet est en mode développement, il se penchera sur le serveur local ou sur le serveur Live. Vous pouvez donc définir le concept dynamic-DB ici.
vous devez créer une fonction, puis vous devez l'appeler à l'intérieur de fonction boot () on App\Providers\AppServiceProvide.php
public function boot()
{
DBConnection();
}
J'ai créé Helper Fichier pour cela. donc mon code dans helper.php
function DBConnection()
{
if( env('APP_ENV') == 'local' )
{ $databse_name = "test_me";
$Host = '127.0.0.1';
$user="root";
$password="";
}
else
{
$databse_name = 'tic_tac';
$Host = 'localhost';
$user="";
$password="";
}
$state = true;
try {
Config::set('database.connections.myConnection', array(
'driver' => 'mysql',
'Host' => $Host,
'database' => $databse_name,
'username' => $user,
'password' => $password,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
));
/* \DB::setDefaultConnection('myConnection');
$state = \DB::connection()->getPdo();*/
Config::set('database.connections.myConnection.database', $databse_name);
\DB::setDefaultConnection('myConnection');
\DB::reconnect('myConnection');
} catch( \Exception $e) {
$state = false;
}
return $state;
}
Si vous entendez utiliser une connexion à une base de données différente, elle existe dans les documents:
Schema::connection('foo')->create('users', function (Blueprint $table) {
$table->bigIncrements('id');
});
Je pense que j'ai finalement compris ce gâchis ... Cette solution n'a pas besoin d'une configuration pour la base de données de chaque locataire et doit être exécutée une seule fois.
class MigrationBlah extends Migration {
public function up() {
$dbs = DB::connection('tenants')->table('tenants')->get();
foreach ($dbs as $db) {
Schema::table($db->database . '.bodegausuarios', function($table){
$table->foreign('usuario')->references('usuarioid')->on('authusuarios');
});
}
}
}
Où j'ai une connexion nommée "tenants" sur mon database.php, qui contient le nom de la base de données de tous mes locataires. J'ai également la connexion par défaut à ma base de données de locataires. Cette base de données est celle chargée de prendre en charge la table des migrations.
Avec l'instruction foreach, elle passe par les bases de données des locataires et exécute la migration sur chacune d'elles.
Sur votre connexion par défaut, vous devez configurer un utilisateur qui a accès à toutes les bases de données du locataire pour que cela fonctionne.
Il est fastidieux de se rappeler quelle migration correspond à quelle base de données.
Pour Laravel 5.5 j'ai utilisé cette approche:
public function up()
{
// this line is important
Illuminate\Support\Facades\DB::setDefaultConnection('anotherDatabaseConnection');
Schema::table('product',
function (Blueprint $table)
{
$table->string('public_id', 85)->nullable()->after('ProductID');
});
// this line is important, Probably you need to set this to 'mysql'
Illuminate\Support\Facades\DB::setDefaultConnection('nameOfYourDefaultDatabaseConnection');
}
Toutes les migrations peuvent être exécutées automatiquement sans avoir à spécifier manuellement la base de données lors de leur exécution.
Veuillez noter que la table des migrations est stockée dans votre base de données par défaut.