Как использовать несколько баз данных в 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();
Полезные ссылки
- Laravel 5 множественное подключение к базе данных ОТ
laracasts.com
- Соедините несколько баз данных в laravel ОТ
tutsnare.com
- Несколько соединений с БД в 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(...);