overview - Comment utiliser dynamiquement plusieurs bases de données pour un modèle dans CakePHP




model cakephp 2 (3)

Je n'aime pas l'idée d'écrire le nom réel de la base de données dans le code. Pour plusieurs bases de données, vous disposez du fichier database.php dans lequel vous pouvez définir autant de bases de données que vous le souhaitez.

Si vous voulez "basculer" une base de données pour un modèle spécifique à la volée , utilisez la méthode setDataSource . (voir ici )

Par exemple, si vous avez deux bases de données, vous pouvez les définir dans le fichier database.php comme "default" et "sandbox", par exemple.

Ensuite, dans votre code:

$this->Car->setDataSource('sandbox');

Le sandbox est le nom de la configuration et le nom réel de la base de données est écrit une seule fois dans le fichier database.php.

Ok, ma première question a été modifiée tellement de fois que j'ai choisi de la supprimer et de reformuler ma question. J'ai fait un petit projet de cas de test avec différents noms de modèles pour trouver une solution appropriée à mon problème.

Attention : ne pas mélanger les bases de données avec des tables

Motivation : J'ai séparé les données de l'utilisateur en plusieurs bases de données pour des questions juridiques et de performance.

Actuellement, je travaille sur un projet CakePHP qui a plusieurs User et chaque User a sa propre base de données avec plusieurs tables ( cars est l'une des tables ). Maintenant, j'ai besoin d'expliquer quelque chose d'abord:

Chaque User a sa propre base de données (pas une table, une base de données ), donc les noms de base de données sont les suivants.

  • Application [DATABASE] (Ceci est la base de données principale de l'application)
    • [TABLE] users
    • permissions [TABLE] ( non pertinentes pour cette question )
  • [DATABASE] app_user1 ( User.id 1 possède toute cette base de données )
    • [TABLE] cars (une table entièrement détenue par User.id 1)
  • [DATABASE] app_user2 ( User.id 2 possède toute cette base de données )
    • [TABLE] cars (une table entièrement détenue par User.id 2)
  • etc...

J'ai fait un petit dessin qui pourrait clarifier la base de données / table- définitions et leurs relations avec les modèles:

Le problème!!!

Je ne sais pas à quelle base de données se connecter jusqu'à ce que l' User connecte. L' User et leurs bases de données sont créées dynamiquement, donc je ne peux pas utiliser app/Config/database.php .

Donc, j'écris actuellement une extension sur les classes Model et ConnectionManager pour contourner les comportements basiques de base de données de CakePHP. Ainsi, le modèle Car sait quelle base de données utiliser. Mais j'ai juste le sentiment que cela pourrait être fait plus facilement!

Donc, je suppose que tout se résume à une question:

Y a-t-il un moyen plus facile de faire ça ?!

Merci à tous ceux qui prendront le temps et l'effort de lire et de comprendre mon problème!


Vous pouvez toujours interroger n'importe quelle base de données en utilisant la notation complète dans mysql. F.ex .:

SELECT * FROM my_schema_name.table_name;

Manière de gâteau:

$db = $this->getDataSource();
$query = array(
    'fields' => array('*'),
    'table' => 'my_schema_name.table_name'
);
$stmt = $db->buildStatement($query, $this);
$result = $db->execute($stmt);

Ce monsieur ( Olivier ) a eu le même problème! (Il y a un an) Il a écrit une petite adaptation pour le Controller s! C'est assez petit et il s'avère que cela fonctionne en 1.3 et 2.x.

Quoi qu'il en soit, c'est ma solution finale, que j'ai mis dans l' app/Model/AppModel.php :

class AppModel extends Model
{
  /**
   * Connects to specified database
   *
   * @param String name of different database to connect with.
   * @param String name of existing datasource
   * @return boolean true on success, false on failure
   * @access public
   */
    public function setDatabase($database, $datasource = 'default')
    {
      $nds = $datasource . '_' . $database;      
      $db  = &ConnectionManager::getDataSource($datasource);

      $db->setConfig(array(
        'name'       => $nds,
        'database'   => $database,
        'persistent' => false
      ));

      if ( $ds = ConnectionManager::create($nds, $db->config) ) {
        $this->useDbConfig  = $nds;
        $this->cacheQueries = false;
        return true;
      }

      return false;
    }
}

Et voici comment je l'ai utilisé dans mon app/Controller/CarsController.php :

class CarsController extends AppController
{
  public function index()
  {
    $this->Car->setDatabase('cake_sandbox_client3');

    $cars = $this->Car->find('all');

    $this->set('cars', $cars);
  }

}

Je parie, je ne suis pas le premier ou le dernier avec ce problème. Donc j'espère vraiment que cette information trouvera des gens et la communauté de CakePHP.







multiple-databases