Comment utiliser plusieurs bases de données dans Laravel

225

Je souhaite combiner plusieurs bases de données dans mon système. La plupart du temps, la base de données est MySQL; mais cela peut différer à l'avenir, c'est-à-dire que l'administrateur peut générer de tels rapports qui sont une source d'utilisation d'un système de base de données hétérogène .

Ma question est donc: Laravel fournit-il une façade pour faire face à de telles situations? Ou tout autre cadre a des capacités plus appropriées pour le problème?

Chintan7027
la source

Réponses:

469

En utilisant .env> = 5.0 (testé sur 5.5)

Dans .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database1
DB_USERNAME=root
DB_PASSWORD=secret

DB_CONNECTION_SECOND=mysql
DB_HOST_SECOND=127.0.0.1
DB_PORT_SECOND=3306
DB_DATABASE_SECOND=database2
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=secret

Dans config/database.php

'mysql' => [
    'driver'    => env('DB_CONNECTION'),
    'host'      => env('DB_HOST'),
    'port'      => env('DB_PORT'),
    'database'  => env('DB_DATABASE'),
    'username'  => env('DB_USERNAME'),
    'password'  => env('DB_PASSWORD'),
],

'mysql2' => [
    'driver'    => env('DB_CONNECTION_SECOND'),
    'host'      => env('DB_HOST_SECOND'),
    'port'      => env('DB_PORT_SECOND'),
    'database'  => env('DB_DATABASE_SECOND'),
    'username'  => env('DB_USERNAME_SECOND'),
    'password'  => env('DB_PASSWORD_SECOND'),
],

Remarque: Dans le mysql2cas DB_username et DB_PASSWORD est la même, vous pouvez utiliser env('DB_USERNAME')qui est metioned en .envpremières lignes.

Sans .env<5,0

Définir les connexions

app/config/database.php

return array(

    'default' => 'mysql',

    'connections' => array(

        # Primary/Default database connection
        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => '127.0.0.1',
            'database'  => 'database1',
            'username'  => 'root',
            'password'  => 'secret'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),

        # Secondary database connection
        'mysql2' => array(
            'driver'    => 'mysql',
            'host'      => '127.0.0.1',
            'database'  => 'database2',
            'username'  => 'root',
            'password'  => 'secret'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
    ),
);

Schéma

Pour spécifier la connexion à utiliser, exécutez simplement la connection()méthode

Schema::connection('mysql2')->create('some_table', function($table)
{
    $table->increments('id'):
});

Générateur de requêtes

$users = DB::connection('mysql2')->select(...);

Éloquent

Définissez la $connectionvariable dans votre modèle

class SomeModel extends Eloquent {

    protected $connection = 'mysql2';

}

Vous pouvez également définir la connexion lors de l'exécution via la setConnectionméthode ou la onméthode statique:

class SomeController extends BaseController {

    public function someMethod()
    {
        $someModel = new SomeModel;

        $someModel->setConnection('mysql2'); // non-static method

        $something = $someModel->find(1);

        $something = SomeModel::on('mysql2')->find(1); // static method

        return $something;
    }

}

Remarque Soyez prudent lorsque vous tentez de créer des relations avec des tables dans des bases de données! Il est possible de le faire, mais il peut être assorti de certaines mises en garde et dépend de la base de données et / ou des paramètres de base de données dont vous disposez.


De Laravel Docs

Utilisation de plusieurs connexions à la base de données

Lorsque vous utilisez plusieurs connexions, vous pouvez accéder à chacune connectionvia la méthode de connexion sur la DBfaçade. Le namepassé à la connectionméthode doit correspondre à l'une des connexions répertoriées dans votre config/database.phpfichier de configuration:

$users = DB::connection('foo')->select(...);

Vous pouvez également accéder à l'instance PDO brute sous-jacente à l'aide de la méthode getPdo sur une instance de connexion:

$pdo = DB::connection()->getPdo();

Liens utiles

  1. Connexion à plusieurs bases de données Laravel 5 laracasts.com
  2. Connectez plusieurs bases de données dans laravel FROM tutsnare.com
  3. Connexions DB multiples dans Laravel fideloper.com
Abdulla Nilam
la source
1
Vous pouvez utiliser class SomeModel extends Model { et également vous assurer que vous avez supprimé les valeurs get du fichier env comme env('DB_DATABASE', 'name')lorsque vous créez un nouveau tableau de configuration DB dans le fichier database.php comme @sba l'a mentionné
Sadee
1
Hé, j'utilise Lumen et pour la partie de configuration de la base de données, je n'ai que le fichier ".env". Pas database.php. Alors, comment puis-je résoudre ce problème?
Chanaka De Silva
1
@ChanakaDeSilva Vous venez de créer un dossier de configuration et un fichier database.php dedans pour Lumen. Apparemment, Lumen vérifie constamment si ce fichier existe et l'utilisera si tel est le cas.
Ecksters
2
Merci frère je pense que je prends ce travail maintenant; p
binar
1
@AbdullaNilam some1 est venu me voir pour faire une application multidb d'abord, je ne sais pas si c'est possible maintenant je sais que c'est simple; p
binar
12

Dans Laravel 5.1, vous spécifiez la connexion:

$users = DB::connection('foo')->select(...);

Par défaut, Laravel utilise la connexion par défaut. C'est simple, non?

En savoir plus ici: http://laravel.com/docs/5.1/database#accessing-connections

schellingerht
la source
dans Laravel 5.1, qu'en est-il d'Eloquent?
simo
1
@simo, voir la réponse d'Abdulla.
schellingerht
J'ai écrit un article complet pour le sam, vous pouvez le vérifier à <a href=" stackcoder.in/posts/… 7.x Connexions à plusieurs bases de données, migrations, relations et
requêtes</a>
6

En fait, DB::connection('name')->select(..)ça ne marche pas pour moi, car 'nom' doit être entre guillemets: "nom"

Pourtant, la requête de sélection est exécutée sur ma connexion par défaut. Toujours en train de comprendre comment convaincre Laravel de fonctionner comme prévu: changez la connexion.

Edit: je l'ai compris. Après avoir débogué Laravels DatabaseManager, il s'est avéré que mon database.php (fichier de configuration) (dans $ this-> app) était incorrect. Dans la section "connexions", j'avais des trucs comme "base de données" avec les valeurs de celle à partir de laquelle je les ai copiés. En termes clairs, au lieu de

env('DB_DATABASE', 'name')

Je devais placer quelque chose comme

'myNewName'

car toutes les connexions ont été répertoriées avec les mêmes valeurs pour la base de données, le nom d'utilisateur, le mot de passe, etc., ce qui n'a bien sûr aucun sens si je veux accéder à au moins un autre nom de base de données

Par conséquent, chaque fois que je voulais sélectionner quelque chose dans une autre base de données, je me retrouvais toujours dans ma base de données par défaut

sba
la source
1
Je vous remercie! Vous avez sauvé ma raison. J'ai essayé de comprendre pourquoi toutes mes requêtes faisaient référence à la base de données par défaut. Ensuite, j'ai lu votre message et j'ai réalisé que env renvoyait toujours les valeurs .env et que le deuxième paramètre n'était qu'une solution de rechange que Laravel n'a pas utilisée.
Moha
Hors sujet: ce serait génial si les administrateurs ne manipulaient pas mes messages. Ou au moins écrivez-moi un message privé quoi et pourquoi ils veulent changer. Je n'ai pas compris comment envoyer des messages privés.
sba
J'ai eu un problème similaire, j'ai changé la valeur mais pas la clé. Cela fonctionnait comme ceci: 'database' => env ('DB_NEW_DATABASE', 'myNewDatabase'). Bien noté!
Fellipe Sanches
0

Laravel a un support intégré pour plusieurs systèmes de base de données, vous devez fournir les détails de connexion dans le fichier config / database.php

return [
    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
'mysqlOne' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST_ONE', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE_ONE', 'forge'),
            'username' => env('DB_USERNAME_ONE', 'forge'),
            'password' => env('DB_PASSWORD_ONE', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
];

Une fois que vous avez cela, vous pouvez créer deux classes de modèle de base pour chaque connexion et définir le nom de la connexion dans ces modèles

//BaseModel.php
protected $connection = 'mysql';

//BaseModelOne.php
protected $connection = 'mysqlOne';

Vous pouvez étendre ces modèles pour créer plus de modèles de tables dans chaque base de données.

sumit
la source