Development

Documentation/fr_FR/book/trunk/populate (diff)

You must first sign up to be able to contribute.

Changes from Version 1 of Documentation/fr_FR/book/trunk/populate

Show
Ignore:
Author:
clochix (IP: 213.41.240.148)
Timestamp:
12/26/06 23:14:56 (11 years ago)
Comment:

Translation creation

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/fr_FR/book/trunk/populate

    v0 v1  
     1{{{ 
     2#!html 
     3<div style="border: solid 2px #f80;padding:10px;margin:5px;background-color: #fdb"> 
     4}}} 
     5Cette partie de la documentation est en cours de traduction. Cela signifie qu'elle est traduite de manière soit incomplète, soit inexacte. En attendant que cette traduction soit terminée, vous pouvez consulter la [http://www.symfony-project.com/book/trunk/populate version en anglais] pour des informations plus fiables. 
     6{{{ 
     7#!html 
     8</div> 
     9}}} 
     10 
     11== Charger une base de données == 
     12 
     13=== En résumé === 
     14 
     15Au cours du développement d'applications, les développeurs sont souvent confrontés au problème de la saisie de données de test dans la base. Des solutions spécifiques à certaines bases existent, mais aucune ne peut s'utiliser de manière générique pour toute base de données relationelle. Symfony offre une solution permettant d'insérer via un script des données en base à partir d'un fichier YAML et de la classe `sfPropelData`. 
     16 
     17=== Introduction === 
     18 
     19Imaginez un projets utilisant des utilisateurs stockés dans une table `User`possédant les colonnes suivantes: 
     20 
     21|| ''User'' || 
     22|| id              || 
     23|| name            || 
     24|| login           || 
     25|| hashed_password || 
     26|| email           || 
     27|| created_at      || 
     28 
     29La classe Propel `User` correspondante contient les méthodes d'accès standards aux propriétés de l'objet. Pour ce projet, on ajoute à la classe une méthode `setPassword()` qui met à jour la colonne `hashed_password` à partir d'un pot de passe en clair. Cette méthode est ajoutée dans le fichier `myproject/lib/model/User.class.php`: 
     30{{{ 
     31[php] 
     32class User extends BaseUser 
     33{  
     34  ... 
     35  public function setPassword($password) 
     36  { 
     37    $this->setHashedPassword(md5(password)); 
     38  } 
     39} 
     40}}} 
     41Cette méthode enregistre dans la colonne hashed_password un MD5 de la valeur passée en argument, pour ne pas stocker de mots de passe en clair dans la base. 
     42 
     43La colonne ìd` est auto-incrémentée. 
     44 
     45Symfony permet d'importer des données dans la base à partir d'un fichier texte, pour préparer des tests unitaires ou réinitialiser la base de développement par exemple. 
     46 
     47=== Syntaxe du fichier === 
     48 
     49Symfony peut lire des fichiers utilisant la syntaxe [http://www.yaml.org/ YAML]. Le fichier se compose d'un entête définissant la classe des enregistrements à insérer dans la base, suivi d'une liste d'enregistrements, chacun identifié par un label unique. Les valeurs de chaque enregistrement sont fixées au moyen de paires `colonne: valeur`. Par exemple: 
     50{{{ 
     51User: 
     52      bob_walter: 
     53        name:       Bob Walter 
     54        login:      bwalter 
     55        password:   sarah34 
     56        email:      bob.walter@foomail.com 
     57         
     58      peter_clive: 
     59        name:       Peter Clive 
     60        login:      pclive 
     61        password:   gurzikso 
     62        email:      peter.clive@foomail.com 
     63}}} 
     64Les noms des colonnes seront transformés en CamelCase pour déterminer la correspondance avec les méthodes de la classe ( ici `->setName()`, `->setLogin()`, `->setPassword()`, `->setEmail()`). Cela signifie qu'il est possible de définir dans le fichier un champ `password` même si la table ne contient pas de colonne `password`. La classe `User` possède une méthode `->setPassword()` qui sera utilisée. 
     65 
     66La colonne `id` étant incrémentée automatiquement, il n'est pas nécessaire de la définir, la couche d'abstraction de base de données s'en chargera. 
     67 
     68La colonne `created_at` n'a pas non plus besoin d'être définie, car Symfony renseigne automatiquement les champs `created_at` et `updated_at` respectivement avec les dates de création et de mise à jour de l'enregistrement. 
     69 
     70Les données à charger sont enregistrées dans un fichier `import_data.yml` dans le répertoire `myproject/data/fixtures/`. 
     71 
     72=== Traitement d'import d'import === 
     73 
     74==== Initialisations ==== 
     75 
     76L'import se fait au moyen d'un script PHP qui lit les données dans des fichiers YAML et les charge en base. Ce script utilise les classes Propel et les fichiers de configuration de Symfony, il doit donc contenir les même initialisations qu'un contrôleur: 
     77 
     78{{{ 
     79    [php] 
     80    <?php 
     81     
     82    define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/..')); 
     83    define('SF_APP',         'myapp'); 
     84    define('SF_ENVIRONMENT', 'dev'); 
     85    define('SF_DEBUG',       true); 
     86     
     87    require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); 
     88     
     89    sfContext::getInstance(); 
     90}}} 
     91 
     92La définition d'une application (`myapp`) et d'un environnement (`dev`) permettent à Symfony de déterminer la configuration à utiliser. Ce code rend accessible les classes Propel et les fonctions de chargement automatique des classes Symfony. 
     93 
     94==== L'appel à `sfPropelData` ==== 
     95 
     96`sfPropelData` est une classe qui permet de lire des données dans un fichier YAML et de les insérer via Propel dans une base de données. Pour l'utiliser, il suffit d'appeler la méthode `->loadData()`. Celle-ci prend pour argument soit le fichier à charger, soit un répertoire contenant plusieurs fichiers à charger. 
     97 
     98Pour charger les données des fichiers contenus dans le répertoire fixtures, créez un fichier `load_data.php` dans le répertoire `myproject/batch/`. Ce fichier contient les initialisations précédentes et l'appel à `sfPropelData`: 
     99{{{ 
     100    [php] 
     101    $data = new sfPropelData(); 
     102    $data->loadData(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures'); 
     103 
     104  ?> 
     105}}} 
     106 
     107Pour exécuter le script, il suffit de taper en ligne de commande: 
     108 
     109{{{ 
     110    $ cd myproject/batch 
     111    $ php load_data.php 
     112}}} 
     113 
     114Cel va charger les deux enregistrements libellés `bob_walter` et  `peter_clive` dans la base (si les paramètres de connection fournis dans le fichier de configuration `myproject/apps/myapp/config/databases.yml` sont corrects). 
     115 
     116''Note'': si vous avez ajouté une connection ou modifié le nom de la connection par défaut (`'propel'`) dans le fichier `databases.yml`, vous devrez spécifier le nom de la connection à utiliser en le passant en paramètre à la méthode `->loadData()`. Par exemple, pour utiliser la connection `symfony`, la syntaxe est: 
     117{{{ 
     118         [php] 
     119         $data->loadData(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures', 'symfony'); 
     120}}} 
     121 
     122=== Ajouter ou remplacer === 
     123 
     124Par défaut, la méthode `->loadData()` supprime tous les enregistrements existant dans les tables chargées. Pour modifier ce comportement, avant d'appeler `->loadData()` il faut positionner la propriété `deleteCurrentData` de `sfPropelData` à faux`: 
     125{{{ 
     126    [php] 
     127    $data->setDeleteCurrentData(false); 
     128 }}} 
     129  
     130Pour obtenir la valeur actuelle de la propriété, utilisez son accesseur: 
     131{{{ 
     132    [php] 
     133    $status = $data->getDeleteCurrentData(false); 
     134}}} 
     135 
     136== Tables liées == 
     137 
     138Ajouter des enregistrements dans une table est aisé, cela peut se compliquer lorsque des tables sont liées entre elles. Imaginez que les utilisateurs de votre site postent des billets via une interface de blog. Votre modèle de données contient donc également une table billet comportant ces champs: 
     139 
     140||     ''Post''        || 
     141|| id              || 
     142|| user_id         || 
     143|| title           || 
     144|| body            || 
     145|| created_at      || 
     146|| updated_at      || 
     147 
     148Comment définir la valeur du champ `user_id` alors que la colonne `id` de la table `User` est renseignée automatiquement ? 
     149 
     150C'est ici que la notion de label devient vraiment utile: pour ajouter un billet écrit par Bob Walter, il suffit d'ajouter les lignes suivantes au fichier `myproject/data/fixtures/import_data.yml`: 
     151{{{ 
     152    Post: 
     153      post01: 
     154        user_id:      bob_walter 
     155        title:        Today is the first day of the rest of my life 
     156        body:         I have plenty to say, but I prefer to stay short. Enjoy. 
     157}}} 
     158 
     159La classe `sfPropelData` va reconnaître le label que vous avez attribué plus haut à un utilisateur, et le remplacer par la clé primaire de l'enregistrement correspondant de la table `User`. Vous liez les objets par leur label, sans vous soucier de leur identifiant. 
     160 
     161La seule contrainte est que l'objet référencé dans une clé étrangère doit avoir été défini plus haut dans le fichier, Vous devez insérer les objets dans le fichier dans l'ordre où vous les inséreriez manuellement. Le fichier est lu de la première à la dernière ligne, et l'ordre dans lequel vous saisissez les données est important. 
     162 
     163=== Un seul fichier ou plusieurs ? === 
     164 
     165Un fichier peu contenir les données pour charger plusieurs tables. Par exemple, le fichier suivant: 
     166{{{ 
     167    User: 
     168      bob_walter: 
     169        name:         Bob Walter 
     170        login:        bwalter 
     171        password:     sarah34 
     172        email:        bob.walter@foomail.com 
     173         
     174      peter_clive: 
     175        name:         Peter Clive 
     176        login:        pclive 
     177        password:     gurzikso 
     178        email:        peter.clive@foomail.com 
     179 
     180    Post: 
     181      test_post: 
     182        user_id:      bob_walter 
     183        title:        Today is the first day of the rest of my life 
     184        body:         I have plenty to say, but I prefer to stay short. Enjoy. 
     185 
     186      another_test_post: 
     187        user_id:      bob_walter 
     188        title:        I don't know what to say today 
     189        body:         As my previous post was so briliant, I find myself a little dry. 
     190        
     191    Comment: 
     192      enthusiast_comment: 
     193        user_id:      peter_clive 
     194        post_id:      test_post 
     195        body:         Hey Bob, I'm so glad you finally found something interesting to say. 
     196           
     197      disappointed_comment: 
     198        user_id:      peter_clive 
     199        post_id:      another_test_post 
     200        body:         Mate, you really disappoint me. I expected much more or your great potential. 
     201}}} 
     202 
     203Ce fichier est long. Symfony vous autorise à le découper. Tous les fichiers d'un répertoire sont traités les uns après les autres, par ordre alphabétique. Vous pouvez par exemple découper le fichier précédent en 3, un pour chaque classe. Pour vous assurer qu'ils seront traités dans le bon ordre, préfixez les noms de fichiers d'un nombre: 
     204{{{ 
     205    100_user_import_data.yml 
     206    200_post_import_data.yml 
     207    300_comment_import_data.yml 
     208}}} 
     209 
     210Comme on l'a appelée avec un répertoire en paramètre, la méthode`->loadData()` du script de chargement fonctionnera toujours. 
     211{{{ 
     212    [php] 
     213    $data->loadData(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures'); 
     214}}} 
     215 
     216Si vous ne voulez charger qu'un seul de ces fichiers: 
     217{{{ 
     218    [php] 
     219    $data->loadData(sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures'.DIRECTORY_SEPARATOR.'100_user_import_data.yml'); 
     220}}} 
     221 
     222=== Syntaxe YAML alternative === 
     223 
     224YAML propose une syntaxe alternative pour les tableaux associatifs. Avec cette syntaxe, vos fichiers de données seront plus lisibles, surtout pour les tables qui contiennent de nombreuses clés étrangères. Par exemple, le fichier 
     225{{{ 
     226Comments: 
     227      c123: 
     228        user_id:    u65 
     229        post_id:    p23 
     230        body:       first blabla 
     231       
     232      c456: 
     233        user_id:    u97 
     234        post_id:    p64 
     235        body:       second blabla 
     236}}} 
     237Peut être écrit plus simplement  
     238{{{ 
     239    Comments: 
     240      c123: { user_id: u65, post_id: p23, body: first blabla } 
     241      c456: { user_id: u97, post_id: p64, body: second blabla } 
     242}}} 
     243 
     244Pour plus d'information sur la syntaxe YAML, reportez-vous [http://www.yaml.org/ au site de YAML] 
     245