У меня две базы данных, и каждая база данных имеет одну и ту же таблицу с одинаковыми полями, но как мне получить все записи из всех двух баз данных одновременно в Yii 2.0?
Множественные подключения к базе данных и Yii 2.0
Ответы (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();
public static function getDb()
использовать static, потому что он переопределяет статический метод.
- person bowpunya; 08.10.2017
Просто чтобы добавить: я последовал предоставленному ответу, но все равно получил ошибку: «Неизвестный идентификатор компонента: 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'),
Спасибо
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
Если вы используете schmunk42/yii2-giiant
для создания классов моделей, есть свойство 'modelDb'
, которое вы можете установить использовать компонент базы данных, отличный от 'db'
.