flosy.info | Développement Web, Open source …

TAG | doctrine

Pour un projet je souhaite pouvoir me connecter à 2 bases de données différentes. Voyons comment faire cela avec Doctrine.

Configuration des bases de données

Nous définissons une connexion pour chacune des bases dans le fichier /config/databases.yml.

all:
  main:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:host=localhost;dbname=base_main'
      username: user
      password: password

  subsidiary:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:host=localhost;dbname=base_subsidiary'
      username: user
      password: password

Définition du modèle

Nous créons ensuite notre schéma en précisant pour chaque classe du modèle la connexion à utiliser. Voici un exemple de schéma :

Utilisateur:
  connection: main
  columns:
    id:         { type: integer, primary: true, autoincrement: true }
    nom:        { type: string(255) }
    
Groupe:
  connection: subsidiary
  columns:
    id:         { type: integer, primary: true, autoincrement: true }
    nom:        { type: string(255) }

La commande de création du modèle va ajouter les tables dans leur base respective.

$ symfony doctrine:build --all

Vous noterez dans les classes de base du modèle la référence à la connexion.

1
2
3
< ?php
  // Connection Component Binding
  Doctrine_Manager::getInstance()->bindComponent('Groupe', 'subsidiary');

À partir de maintenant les données seront enregistrées dans les 2 bases de données.

Related Posts:

·

Je souhaitais utiliser la méthode copy de Doctrine_Record pour dupliquer un objet et les objets auxquels il est associé.
Pour cela il suffit de placer le paramètre $deep de la méthode copy à true, du moins c’est ce que je pensais.
Pour que cela fonctionne il faut charger au préalable les relations qui nous intéressent. (C’est très bien expliqué dans cet article http://david-gueye.fr/2010/02/02/dupliquer-ou-cloner-un-objet-doctrine-record/).

Voici un petit exemple :

  $groupe = Doctrine_Core::getTable("Groupe")->find(1);
  $groupe->loadReference("Utilisateurs");
  $copieGroupe = $groupe->copy(true);
  $copieGroupe->save();

Related Posts:

L’une des classes de mon modèle dispose d’un attribut default. Voici un extrait du schéma qui montre l’élément en question.

Group:
  columns:
    id:        { type: integer, primary: true, autoincrement: true }
    name:      { type: string(255) }
    default:    { type: boolean }

Lors de la création du modèle l’erreur suivante apparaît :

$ symfony doctrine:build --all
...
>> doctrine  generating sql for models
>> doctrine  Generated SQL successfully for models
>> doctrine  creating tables
 
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'default TINYINT(1), PRIMARY KEY(id)) ENGINE =
INNODB' at line 1. Failing Query: "CREATE TABLE group (id BIGINT AUTO_INCREMENT, name VARCHAR(255), default 
TINYINT(1), PRIMARY KEY(id)) ENGINE = INNODB". Failing Query: CREATE TABLE group (id BIGINT AUTO_INCREMENT, 
name VARCHAR(255), default TINYINT(1), PRIMARY KEY(id)) ENGINE = INNODB

Si nous observons le script SQL produit dans data/sql/schema.sql nous trouvons :

CREATE TABLE GROUP (id BIGINT AUTO_INCREMENT, name VARCHAR(255), DEFAULT TINYINT(1), PRIMARY KEY(id)) ENGINE = INNODB;

DEFAULT est un mot clé réservé aussi pour l’utiliser il nous faut échapper le nom du champ avec des backquotes.

Un ticket sur le trac du projet symfony explique ce problème (le ticket en question).

Nous utilisons la méthode configureDoctrine de ProjectConfiguration pour paramétrer doctrine.

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->enablePlugins('sfDoctrinePlugin');
  }
 
  public function configureDoctrine(Doctrine_Manager $manager)
  {
    $manager->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true);
  }
}

Cette fois le script SQL échappe les noms de champ.

CREATE TABLE `group` (`id` BIGINT AUTO_INCREMENT, `name` VARCHAR(255), `default` TINYINT(1), PRIMARY KEY(`id`)) ENGINE = INNODB;

Update

Dans le cas d’un nom de BDD avec un tiret, cette astuce est nécessaire (par exemple ma-bdd).

Related Posts:

· ·

La version 1.4 de symfony avec Doctrine fournit des méthodes pour utiliser la classe DateTime dans le model.
La classe DateTime ainsi que DateTimeZone sont disponibles depuis PHP 5.2.0.
Elles permettent de fournir un support Objet pour les dates, heures et fuseaux horaires.
Attention tout de même la méthode DateTime::diff fait appel à l’objet DateInterval disponible seulement depuis la version PHP 5.3.0.

Related Posts:

· ·

Theme Design by devolux.nh2.me