Come utilizzare più database in Laravel


225

Voglio combinare più database nel mio sistema. Il più delle volte il database è MySQL; ma potrebbe differire in futuro, vale a dire che l'amministratore può generare tali report che è fonte di utilizzo di un sistema di database eterogeneo .

Quindi la mia domanda è : Laravel fornisce una facciata per affrontare tali situazioni? O qualsiasi altro framework ha capacità più adatte al problema?

Risposte:


469

Utilizzando .env> = 5.0 (testato su 5.5)

Nel .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

Nel 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'),
],

Nota: In mysql2caso DB_username e password_db è lo stesso, quindi è possibile utilizzare env('DB_USERNAME')che è metioned in .envprime righe.

Senza .env<5.0

Definisci connessioni

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'    => '',
        ),
    ),
);

Schema

Per specificare quale connessione utilizzare, è sufficiente eseguire il connection()metodo

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

Query Builder

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

Eloquente

Imposta la $connectionvariabile nel tuo modello

class SomeModel extends Eloquent {

    protected $connection = 'mysql2';

}

È inoltre possibile definire la connessione in fase di esecuzione tramite il setConnectionmetodo o il onmetodo statico:

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;
    }

}

Nota Prestare attenzione a tentare di costruire relazioni con le tabelle nei database! È possibile farlo, ma può venire con alcuni avvertimenti e dipende dal database e / o dalle impostazioni del database che hai.


Da Laravel Docs

Utilizzo di più connessioni al database

Quando si utilizzano più connessioni, è possibile accedere a ciascuna connectiontramite il metodo di connessione sulla DBfacciata. Il namepassaggio al connectionmetodo deve corrispondere a una delle connessioni elencate nel config/database.phpfile di configurazione:

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

È inoltre possibile accedere all'istanza PDO sottostante non elaborata utilizzando il metodo getPdo su un'istanza di connessione:

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

link utili

  1. Laravel 5 connessione multipla al database DA laracasts.com
  2. Connetti più database in laravel FROM tutsnare.com
  3. Connessioni DB multiple in Laravel FROM fideloper.com

1
È possibile utilizzare class SomeModel extends Model { e assicurarsi anche di aver rimosso i valori dal file env come env('DB_DATABASE', 'name')quando si creava un nuovo array di configurazione DB nel file database.php come accennato da @sba
Sadee,

1
Ehi, sto usando Lumen e per la parte di configurazione del database, ho solo il file ".env". Non database.php. Quindi, come posso risolvere questo?
Chanaka De Silva,

1
@ChanakaDeSilva Basta creare una cartella di configurazione e un file database.php per Lumen. Apparentemente Lumen verifica costantemente se quel file esiste e lo userà in caso affermativo.
Ecksters,

2
Grazie fratello, penso di accettare questo lavoro ora; p
binar,

1
@AbdullaNilam some1 è venuto da me per creare un'app multidb inizialmente pensavo che non sapessi se fosse possibile ora so la sua semplicità; p
binar

12

In Laravel 5.1, si specifica la connessione:

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

Predefinito, Laravel utilizza la connessione predefinita. È semplice, no?

Maggiori informazioni qui: http://laravel.com/docs/5.1/database#accessing-connections


in Laravel 5.1, che dire di Eloquent?
simo

1
@simo, vedi la risposta di Abdulla.
schellingerht,

Ho scritto un articolo completo per il sam che puoi consultare su <a href=" stackcoder.in/posts/… 7.x Connessioni multiple al database, Migrazioni, Relazioni e
query</a>

6

In realtà, non DB::connection('name')->select(..)funziona per me, perché 'name' deve essere tra virgolette doppie: "name"

Tuttavia, la query di selezione viene eseguita sulla mia connessione predefinita. Sto ancora cercando di capire come convincere Laravel a lavorare nel modo previsto: cambiare la connessione.

Modifica: l'ho capito. Dopo il debug di Laravels DatabaseManager è risultato che il mio database.php (file di configurazione) (all'interno di $ this-> app) era sbagliato. Nella sezione "connessioni" avevo cose come "database" con i valori di quello da cui l'ho copiato. In termini chiari, invece di

env('DB_DATABASE', 'name')

Avevo bisogno di posizionare qualcosa di simile

'myNewName'

dal momento che tutte le connessioni sono state elencate con gli stessi valori per il database, nome utente, password, ecc. che ovviamente ha poco senso se voglio accedere almeno ad un altro nome di database

Pertanto, ogni volta che volevo selezionare qualcosa da un altro database finivo sempre nel mio database predefinito


1
Grazie! Mi hai salvato la sanità mentale. Ho provato a capire perché tutte le mie query si riferivano al database predefinito. Poi ho letto il tuo post e ho capito che env restituiva sempre i valori .env e il secondo parametro era solo un fallback che Laravel non usava.
Moha,

Fuori tema: sarebbe fantastico se gli amministratori non manipolassero i miei post. O almeno scrivimi un messaggio privato che cosa e perché vogliono cambiare. Non ho capito come inviare messaggi privati.
sba,

Ho avuto un problema simile, ho cambiato il valore ma non la chiave. Funzionava così: 'database' => env ('DB_NEW_DATABASE', 'myNewDatabase'). Ben annotato!
Fellipe Sanches,

0

Laravel ha il supporto integrato per più sistemi di database, è necessario fornire i dettagli di connessione nel file 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,
        ],
];

Una volta ottenuto questo, è possibile creare due classi di modelli di base per ciascuna connessione e definire il nome della connessione in tali modelli

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

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

È possibile estendere questi modelli per creare più modelli per le tabelle in ciascun DB.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.