Symfony et Doctrine : connexions multiples

6 gravatar Par Grégoire Marchal - 02/09/2010

Bon, ok, pour un premier article, je ne me lance pas dans un concept super compliqué et inconnu de tous, certes. Considérons ça comme un rodage ! Je vais donc tâcher de faire un petit article sur ma récente première utilisation de connexions multiples à des bases de données, avec Symfony 1.4 et Doctrine 1.2.

A la base, mon projet se connectait à une seule base, la configuration classique, la routine. Un beau jour, j'ai eu besoin d'aller mettre à jour la valeur d'un champ dans une autre base de données. Deux possibilités se présentaient :

  • utiliser les infâmes fonctions mysql_*() comme dans les années 80 (bon, c'est peut-être pas si vieux, mais presque)
  • découvrir le monde merveilleux des connexions Doctrine multiples

Ne m'étant jamais penché sur ce point, j'avais peur que la seconde option soit trop lourde. Mais conseillé par mes collaborateurs d'SQL Technologies, la tâche s'est avérée finalement très simple.

Premièrement, il a fallu modifier le fichier config/databases.yml afin qu'il prenne en compte la seconde connexion :

# databases.yml
all:
  connection1:
    class:        sfDoctrineDatabase
    param:
      ...
  connection2:
    class:        sfDoctrineDatabase
    param:
      ...

J'ai ensuite introspecté cette seconde base pour que Symfony génère son schéma (vous pouvez le faire à la main si vous êtes courageux !) :

symfony doctrine:build-schema

Et là, magie : dans le fichier config/doctrine/schema.yml, on voit désormais que chaque table est liée à une des deux connexions grâce au paramètre... "connection" !

MyTable1:
  connection: connection1
  columns:
    ...
MyTable2:
  connection: connection2
  columns:
    ...

Et lorsque l'on reconstruit le modèle, la magie opère ! Dans les fichiers Base*.class.php du modèle, une nouvelle ligne est apparue, permettant "d'attacher" chaque classe du modèle à sa connexion :

// BaseMyTable1.class.php
// Connection Component Binding
Doctrine_Manager::getInstance()->bindComponent('MyTable1', 'connection1');

Et c'est tout ! On peut alors utiliser nos objets presque sans se soucier d'où proviennent et où vont les données.

// stupid actions
$oObject1 = Doctrine::getTable('MyTable1')->find(7);
$oObject2 = Doctrine::getTable('MyTable2')->find(42);
$oObject2->setName($oObject1->getTitle())->save();

Vive Doctrine, et vive Symfony !

Retour à l'accueil

Commentaires (6)

gravatar Par jp_morvan, le 03/09/2010 à 09:22
Bonjour et bienvenue à toi et à ton blog !

J’ai une petite question concernant les connexion multiples dans le cadre de migrations.
Voici ma situation :
- un projet avec sa base ‘a’
- un plugin de codes postaux qui travaille sur une seule base ‘b’ pour plusieurs projets
- une liaison entre un champ de la base ‘a’ et la table ‘b’

Le projet initial n’est pas nouveau et donc je ne souhaite pas tout rebuilder.

As-tu déjà essayé de travailler les migrations avec les connexions Doctrine car je n’y suis pas arrivé (mais ça fait déjà 4-5 mois).

Merci d’avance et bonne continuation pour ton blog !
gravatar Par Grégoire Marchal, le 03/09/2010 à 16:44
Bonjour et merci.

Malheureusement, je ne suis pas en mesure de répondre à ta question. Je n’ai pas beaucoup travaillé avec les migrations pour le moment. Quel est ton problème exactement ?
gravatar Par Ludo, le 03/09/2010 à 21:46
Pour les multiples connections Doctrine, j’ajouterai également un tips :
l’orm supporte les ForeignKey inter-database. Du coup, on peut faire des choses merveilleuses :)
gravatar Par jp_morvan, le 03/09/2010 à 21:50
Il faudrait que je relise un peu le code mais de mémoire, je génère la migration après modification de mon schéma puis je lance la migration et il n’arrive pas à créer la liaison entre les deux bases (je crois même qu’il me rebuild la base de mon plugin…).

J’avais posté pas mal sur les forums mais personne n’avait de solution.

Il faudra que j’essaye la méthode : Doctrine_Manager::getInstance()->bindComponent(‘MyTable1?, ‘connection1?);

Merci quand même pour l’attention :)
gravatar Par NicoD., le 06/09/2010 à 02:01
Hello !

Bienvenue à toi sur la Blogosphère Symfoniesque !

Si Doctrine est capable des gérer des foreign keys inter-base, ce n’est pas le début du bonheur mais presque… ;-)

J’imagine cependant que les requêtes inter-connexions ou inter-base doivent un peu plus gourmandes en ressources que les classiques.
gravatar Par bourvill, le 18/01/2011 à 18:36
Merci pour l’astuce !

Je vais pouvoir mettre en place un bon moyen de log et de visite pour mes sites!

Commenter