Множественные подключения к базе данных и Yii 2.0

У меня две базы данных, и каждая база данных имеет одну и ту же таблицу с одинаковыми полями, но как мне получить все записи из всех двух баз данных одновременно в Yii 2.0?


person Chhorn Soro    schedule 02.12.2014    source источник


Ответы (4)


Сначала вам нужно настроить свои базы данных, как показано ниже:

return [
'components' => [
    'db1' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=db1name', //maybe other dbms such as psql,...
        'username' => 'db1username',
        'password' => 'db1password',
    ],
    'db2' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=db2name', // Maybe other DBMS such as psql (PostgreSQL),...
        'username' => 'db2username',
        'password' => 'db2password',
    ],
],
];

Тогда вы можете просто:

// To get from db1
Yii::$app->db1->createCommand((new \yii\db\Query)->select('*')->from('tbl_name'))->queryAll()

// To get from db2
Yii::$app->db2->createCommand((new \yii\db\Query)->select('*')->from('tbl_name'))->queryAll()

Если вы используете активную модель записи, в своей модели вы можете определить:

public static function getDb() {
    return Yii::$app->db1;
}

//Or db2
public static function getDb() {
    return Yii::$app->db2;
}

Потом:

Если вы установили db1 в методе getDb(), результат будет извлечен из db1 и так далее.

ModelName::find()->select('*')->all();
person Ali MasudianPour    schedule 02.12.2014
comment
Заранее спасибо за отличный ответ. Это действительно полезно. - person Chhorn Soro; 03.12.2014
comment
Я получаю сообщение об ошибке при использовании вашего кода. Это не совсем неправильно, но я думаю, вы что-то упустили. Вы пропустили 'class' = ›'yii \ db \ Connection' после return [ - person nodeffect; 26.05.2015
comment
У меня ошибка .... В моих моделях я использую Yii :: $ app- ›db1-› createCommand ((new \ yii \ db \ Query) - ›select ('*') -› from (' tbl_name ')) - ›queryAll (); но у меня возникает эта ошибка. Получение неизвестного свойства: yii \ web \ Application :: db1 - person nodeffect; 26.05.2015
comment
Отлично !! Недурно. - person Nana Partykar; 14.03.2016
comment
Я единственный, у кого этот метод статический в ActiveRecord, и я не могу перезаписать его нестатическим методом? - person pgarriga; 04.05.2016
comment
Ваш ответ мне помог ... Спасибо ... Как я могу получить имя базы данных из компонента? Мне нужно использовать его в строке запроса .. - person Chaitanya; 20.05.2016
comment
должен быть public static function getDb() использовать static, потому что он переопределяет статический метод. - person bowpunya; 08.10.2017
comment
Что, если мне нужны данные из второй базы данных с использованием модельного запроса? не createCommand. - person TrickStar; 07.05.2020

Просто чтобы добавить: я последовал предоставленному ответу, но все равно получил ошибку: «Неизвестный идентификатор компонента: db»

После некоторого тестирования я обнаружил следующее: функция getDB вызывается только ПОСЛЕ соединения с db. Следовательно, вы не можете удалить или переименовать db в файле конфигурации. Вместо этого вам нужно позволить вызову 'db' продолжаться как обычно, а затем переопределить его.

Решение (для меня) было следующим:

В config/web.php добавьте вторую конфигурацию базы данных ниже db следующим образом:

'db' => require(__DIR__ . '/db.php'),
'db2' => [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=name',
    'username' => 'user',
    'password' => 'password',
    'charset' => 'utf8',
    'on afterOpen' => function ($event) {
        $event->sender->createCommand("SET time_zone = '+00:00'")->execute();
    },
],

НЕ переименовывайте db. Неспособность найти базу данных вызовет ошибку. Вы можете называть db2 как хотите.

Теперь в модель добавьте следующий код:

class ModelNameHere extends \yii\db\ActiveRecord {

   // add the function below:
   public static function getDb() {
       return Yii::$app->get('db2'); // second database
   }

Теперь это переопределит конфигурацию db по умолчанию.

Я надеюсь, что это поможет кому-то другому.

Примечание: вы можете включить конфигурацию для db2 в другой файл, но не можете включить ее в файл db.php (очевидно). Вместо этого создайте файл с именем db2.php и назовите его так же, как и db:

'db' => require(__DIR__ . '/db.php'),    
'db2' => require(__DIR__ . '/db2.php'),

Спасибо

person DrBorrow    schedule 10.08.2016
comment
Я переименовал «db», и это сработало. Кроме того, ваше решение работает. - person ColinWa; 20.09.2016
comment
Я пробовал ваш, но у меня SQLSTATE[42000]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Incorrect syntax near '='. The SQL being executed was: SET time_zone = '+00:00' есть идеи? Благодарность - person Blackjack; 04.12.2017

Наша ситуация немного сложнее, у нас есть «родительская» база данных, в которой есть таблица, содержащая имя одной или нескольких «дочерних» баз данных. Причина этого в том, что проект Yii создается для каждого из наших клиентов, а количество дочерних баз данных зависит от клиента, а также имена баз данных произвольны (хотя и следуют шаблону).

Итак, мы переопределяем \yii\db\ActiveRecord следующим образом:

class LodgeActiveRecord extends \yii\db\ActiveRecord
{

public static function getDb()
{
    $lodgedb = Yii::$app->params['lodgedb'];
    if(array_key_exists( $lodgedb, Yii::$app->params['dbs'])) {
        return Yii::$app->params['dbs'][ $lodgedb ];
    }
    $connection = new \yii\db\Connection([
        'dsn' => 'mysql:host=localhost;dbname=' . $lodgedb,
        'username' => Yii::$app->params['dbuser'],
        'password' => Yii::$app->params['dbpasswd'],
        'charset' => 'utf8',
    ]);
    $connection->open(); // not sure if this is necessary at this point
    Yii::$app->params['dbs'][ $lodgedb ] = $connection;
    return $connection;
}

}

Перед вызовом любой функции базы данных сначала установите Yii::$app->params['lodgedb'] на имя требуемой базы данных:

Yii::$app->params['lodgedb'] = $lodge->dbname; // used by LodgeActiveRecord

Классы вашей модели не меняются, за исключением того, что они являются наследниками LodgeActiveRecord:

class BookingRooms extends \app\models\LodgeActiveRecord

person Nik Dow    schedule 06.06.2018

Если вы используете schmunk42/yii2-giiant для создания классов моделей, есть свойство 'modelDb', которое вы можете установить использовать компонент базы данных, отличный от 'db'.

person gvlasov    schedule 23.07.2018