Как использовать несколько баз данных в Laravel

Я хочу объединить несколько баз данных в моей системе. Большую часть времени база данных MySQL; но это может отличаться в будущем, т. е. администратор может создавать такие отчеты, которые используют источник гетерогенной системы баз данных.

Таким образом, мой вопрос заключается в том , предоставляет ли Laravel какой-либо Фасад для решения таких ситуаций? Или любой другой фреймворк имеет более подходящие возможности для решения проблемы?

9 ответов

Решение

С помощью .env > = 5.0 (протестировано на 5.5)

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

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

Примечание: в mysql2 если DB_username и DB_password совпадают, то вы можете использовать env('DB_USERNAME') который упоминается в .env первые несколько строк.

Без .env <5,0

Определить соединения

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

схема

Чтобы указать, какое соединение использовать, просто запустите connection() метод

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

Query Builder

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

красноречивый

Установить $connection переменная в вашей модели

class SomeModel extends Eloquent {

    protected $connection = 'mysql2';

}

Вы также можете определить соединение во время выполнения через setConnection метод или on статический метод:

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

}

Примечание. Будьте осторожны при попытке построить отношения с таблицами в разных базах данных! Это можно сделать, но это может сопровождаться некоторыми оговорками и зависит от того, какие настройки базы данных и / или базы данных у вас есть.


Из Laravel Docs

Использование нескольких подключений к базе данных

При использовании нескольких подключений вы можете получить доступ к каждому connection через метод подключения на DB фасад. name перешел к connection метод должен соответствовать одному из соединений, перечисленных в вашем config/database.php конфигурационный файл:

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

Вы также можете получить доступ к необработанному базовому экземпляру PDO, используя метод getPdo для экземпляра соединения:

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

Полезные ссылки

  1. Laravel 5 множественное подключение к базе данных ОТ laracasts.com
  2. Соедините несколько баз данных в laravel ОТ tutsnare.com
  3. Несколько соединений с БД в Laravel ОТ fideloper.com

В Laravel 5.1 вы указываете соединение:

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

По умолчанию Laravel использует соединение по умолчанию. Это просто, не правда ли?

Узнайте больше здесь: http://laravel.com/docs/5.1/database

Laravel имеет встроенную поддержку нескольких систем баз данных, все, что вам нужно, это указать детали подключения в файле 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,
        ],
];

Получив это, вы можете создать два класса базовой модели для каждого соединения и определить имя соединения в этих моделях.

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

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

Вы можете расширить эти модели, чтобы создать больше моделей для таблиц в каждой БД.

На самом деле, DB::connection('name')->select(..) не работает для меня, потому что "имя" должно быть в двойных кавычках: "имя"

Тем не менее, запрос на выбор выполняется на моем соединении по умолчанию. Все еще пытаюсь понять, как убедить Laravel работать так, как он задумал: изменить соединение.

Редактировать: я понял это. После отладки Laravels DatabaseManager оказалось, что мой database.php (файл конфигурации) (внутри $this->app) был неверным. В разделе "соединения" у меня были такие вещи, как "база данных" со значениями того, из которого я его скопировал. Ясно, вместо

env('DB_DATABASE', 'name')

Мне нужно было разместить что-то вроде

'myNewName'

поскольку все соединения были перечислены с одинаковыми значениями для базы данных, имени пользователя, пароля и т. д., что, конечно, не имеет большого смысла, если я хочу получить доступ по крайней мере к другому имени базы данных

Поэтому каждый раз, когда я хотел выбрать что-то из другой базы данных, я всегда попадал в базу данных по умолчанию

Используя Laravel 9 и подключаясь к трем разным базам данных, по умолчанию MySQL и двум другим базам данных Postgres, я обнаружил, что определение отношений моделей работает правильно для моделей из разных баз данных, если я просто устанавливаю$connectionзначение явно для всех моделей, особенно для тех, которые используют подключение к базе данных по умолчанию. Это означает, что если вы измените соединение по умолчанию, вам придется обновить эти модели, но это случается редко, если вообще происходит.

Также вы можете использовать систему postgres fdw

https://www.postgresql.org/docs/9.5/postgres-fdw.html

Вы сможете подключать разные db в postgres. После этого в одном запросе можно получить доступ к таблицам, находящимся в разных базах данных.

Это сработало для меня

Промежуточное ПО:

      <?php 
namespace App\Http\Middleware;

use Config;
use Closure;
use DB;

class DBSelect
{

   public function handle($request, Closure $next)
   {
    //$db_name = "db1";
    $db_name = "db2";
    Config::set('database.connections.mysql.database', $db_name);

    DB::reconnect('mysql');

    return $next($request);
  }
 }

глобальное ядро.php

      protected $middleware = [
    .....
    \App\Http\Middleware\DBSelect::class,
];

Я изменил некоторый код из этого ответа ( /questions/56041795/dinamicheskoe-soedinenie-neskolkih-baz-dannyih-laravel-posle-vhoda-v-sistemu/56041806#56041806), и это сработало для меня.

Не лучшее решение, если вы хотите клонировать существующую систему и запустить существующий код в новой базе данных для нового клиента.

Нам пришлось бы отредактировать сотни красноречивых вызовов, чтобы вставить DB::connection('foo')

Laravel, как и многие современные PHP-фреймворки, использует ORM (объектно-реляционное сопоставление) под названием Eloquent. Eloquent предоставляет удобный и унифицированный API для взаимодействия с различными системами баз данных, но по умолчанию ожидает одно основное соединение. Однако Laravel достаточно гибок, чтобы управлять несколькими подключениями, даже к разнородным базам данных.

Вот как вы можете подойти к ситуации в Laravel:

Несколько подключений к базе данных:

В файле config/database.php вы можете определить несколько подключений к базе данных.

      $users = DB::connection('mysql2')->select(...);
Другие вопросы по тегам