web-dev-qa-db-fra.com

Connexions multiples à la base de données et Yii 2.0

J'ai deux bases de données et chaque base de données a la même table avec les mêmes champs, mais comment puis-je obtenir tous les enregistrements de toutes les deux bases de données en même temps dans Yii 2.0?

52
Chhorn Soro

Vous devez d’abord configurer vos bases de données comme ci-dessous:

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',
    ],
],
];

Ensuite, vous pouvez simplement:

// 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()

Si vous utilisez un modèle d'enregistrement actif, vous pouvez définir dans votre modèle:

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

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

Ensuite:

Si vous avez défini db1 dans la méthode getDb(), le résultat sera extrait de db1, etc.

ModelName::find()->select('*')->all();
97
Ali MasudianPour

Juste pour ajouter: J'ai suivi la réponse fournie mais j'ai quand même eu une erreur: "Identifiant de composant inconnu: db"

Après quelques tests, voici ce que j’ai découvert: La fonction getDB s’appelle uniquement APRÈS QUE une connexion est établie avec db. Par conséquent, vous ne pouvez pas supprimer ou renommer "db" dans le fichier de configuration. Au lieu de cela, vous devez laisser l'appel à 'db' se dérouler normalement et le remplacer ensuite. 

La solution (pour moi) était la suivante:

Dans config/web.php, ajoutez votre deuxième configuration de base de données sous db comme suit:

'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();
    },
],

NE PAS renommer db. Si vous ne trouvez pas la base de données, une erreur se produira. Vous pouvez nommer db2 comme bon vous semble. 

Maintenant, dans le modèle, ajoutez le code suivant:

class ModelNameHere extends \yii\db\ActiveRecord {

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

Cela va maintenant remplacer la configuration par défaut db

J'espère que cela aide quelqu'un d'autre. 

Remarque: vous pouvez inclure la configuration pour db2 dans un autre fichier, mais vous ne pouvez pas l'inclure dans le fichier db.php (évidemment). Au lieu de cela, créez un fichier appelé db2.php et appelez-le comme vous le faites db:

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

Merci

18
DrBorrow

Notre situation est un peu plus complexe, nous avons une base de données "parent" qui a une table qui contient le nom d’une ou plusieurs bases de données "enfants" ... clients, et le nombre de bases de données enfants dépend du client; les noms de bases de données sont également arbitraires (bien qu’ils suivent un modèle).

Nous substituons donc \yii\db\ActiveRecordas comme suit:

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

}

Avant d’appeler une fonction de base de données, commencez par définir Yii::$app->params['lodgedb'] avec le nom de la base de données requis:

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

Les classes de votre modèle ne changent pas, sauf celles qui vont de LodgeActiveRecord:

class BookingRooms extends \app\models\LodgeActiveRecord

0
Nik Dow

Si vous utilisez schmunk42/yii2-giiant pour générer des classes de modèle, vous pouvez définir une propriété 'modelDb' pour utiliser un composant de base de données autre que 'db'.

0
gvlasov