View
1.953
Download
4
Category
Preview:
DESCRIPTION
Citation preview
Optimisez vos imports de données avec Migrate
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Qui suis-je ?
Matthieu Guillermin• Consultant chez Clever Age
• Java, PHP, Symfony, Play!,... et ... Drupal
@mguillermin
2
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Agenda
• Contexte
• Solutions d’import de données dans Drupal
• Anatomie d’une tâche Migrate
• Gestion des références entre contenus
• Stratégies d’optimisation
3
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Imports de données
4
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Imports de données
• Problème récurrent
• Récupération de contenu initial
• Affichage de données depuis sources externes
• Agrégation de données
• ...
5
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Imports de données
• Problématiques variées
• Sources : BDD, fichiers, flux,...
• Structures de donnée : plat, relationnel,...
• Fréquences d’imports : one-shot, quotidient,...
• Cibles : Nodes, Files, Users, Taxonomy,...
6
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Solutions d’import de données dans Drupal
7
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
« A la main »
• Transfert direct vers la base
• Via des scripts
• En utilisant un ETL
• Schéma cible difficile à appréhender
• Encore + depuis Drupal 7
• Risque d’erreurs important
8
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
« A la main »
• En utilisant l’API Drupal pour enregistrer les données
• Développement d’un module
• Implémentation de la lecture des données
• Construction de la structure du node
• Utilisation de node_save() pour l’enregistrement
9
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
« A la main »
• Les +
• Souplesse totale sur la source et les traitements
• Les -
• Beaucoup de travail
• On va « réinventer la roue »
• Difficile de construire la structure « node »
10
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Feeds
• Module « historique » pour l’import de données
• Au départ, plutôt dédié aux flux XML (RSS)
• Configuration UI + API
• Connecteurs disponibles : XML, CSV, LDAP,...
11
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Feeds• Les +
• Rapide à mettre en place
• Configuration via l’interface
• Connecteurs disponibles
• Les -
• Peu adapté aux gros volumes de données
• Difficile de gérer les cas « particuliers »
• Références entre les contenus12
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Migrate
• Module dédié à l’import de données
• Interface graphique minimale
• Nécessite de « coder » les imports
• Fournit des outils clés en main (lancement de tâches, ...)
• Peut faire peur de prime abord
13
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Migrate
• Les +
• Connecteurs fournis
• Performances sur de gros volumes
• Gestion des références entre contenus
• Les -
• Nécessite d’écrire du code
• ça pourrait être un + !
14
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
En résumé
• Feeds
• Si vous voulez une interface simple
• Si il suffit à votre besoin
• Et si vous aimez cliquer
• Sinon, Migrate
• Pas si compliqué que ça
15
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Anatomie d’une tâche Migrate
16
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Source
• Gère le requêtage des données
• SQL : MySQL, Oracle, MSSQL,..
• Fichiers : CSV, XML, ...
• Fournit une série d’enregistrements
• Avec les valeurs des champs
• S’occupe du parcours des données
• Extensible en cas de besoin
17
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Source$query = Database::getConnection('myDb', 'myDbKey') ->select('article', 'a');$query->innerJoin(‘article_category’, ‘ac’, ‘a.category_id = ac.id’);
$query->fields(‘a’, ‘id’);$query->fields(‘a’, ‘title’);$query->fields(‘a’, ‘content’);$query->fields(‘ac’, ‘name’, ‘cat_name’);
$this->source = new MigrateSourceSQL($query, array(), NULL, array('map_joinable' => FALSE));
18
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
$this->source = new MigrateSourceCSV($source_file, $this->csvcolumns(), array('header_rows' => 1), array());
function csvcolumns() { $columns[0] = array('title', 'Title'); $columns[2] = array('desc', 'Description'); return $columns;}
Source
19
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
$items_url = $xml_folder . 'positions.xml';$item_xpath = '/producers/producer'; $item_ID_xpath = 'sourceid';
$this->source = new MigrateSourceXML($items_url, $item_xpath, $item_ID_xpath, $fields);
Source
20
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Destination• Gère l’enregistrement des données
• Types fournis par Migrate :
• User, Role, Node, Comment, Term, File,...
• Utilise l’API pour enregistrer : node_save, user_save(),...
• Extensible
• on peut créer ses propres types de destinations
21
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Destination// Node$this->destination = new MigrateDestinationNode( 'article', array('text_format' => 'full_html'));
// Taxonomy$this->destination = new MigrateDestinationTerm( ‘voc_name’);
// User$this->destination = new MigrateDestinationUser();
22
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Mapping
• Associations champs
• Source => Destination
• Peuvent être simples ou + complexes
• Transformation de données
• Conversion de formats
• ...
23
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Mapping
SRC
SRC_ID
SRC_1
SRC_2
SRC_3
DEST
DEST_ID
DEST_1
DEST_2
DEST_3Transfo.
Transfo.
24
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Mapping
• Transformations de données
• Chaîne ➞ tableau (explode)
• Appel de « Callbacks »
• Arguments
• A utiliser suivant les types de champs
• cf les « Migrate*FieldHandler »
25
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Mapping
26
// Default value$this->addFieldMapping('language', 'lang')->defaultValue('fr');
// Multiple$this->addFieldMapping('field_auteur', 'auteurs')->separator(',');
// Callbacks$this->addFieldMapping('title', 'titre')->callbacks('strip_tags', array($this, 'trimTitle'), array($this, 'convertToUtf8')
);
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Mapping
• « Sous le capot »
• les FieldHandlers s’occupent de convertir les valeurs
• Construction des structures en fonction des types de champs
• Utilise les arguments pour savoir comment les générer
27
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
FieldHandlers
28
// Beforestring(2) "C1"
// After["field_numero"]=> array(1) { ["und"]=> array(1) { [0]=> array(3) { ["value_format"]=> string(10) "plain_text" ["format"]=> string(10) "plain_text" ["value"]=> string(2) "C1" } } }
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Mapping
29
// Arguments Date$date_args = DateMigrateFieldHandler::arguments('Europe/Paris');
$this->addFieldMapping('field_pub_date', 'pub')->arguments($date_args);
// Arguments Term Reference$this->addFieldMapping('field_categorie', 'categorie')->arguments(array('source_type' => 'tname', 'create_term' => TRUE
));
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Map
• Correspondance entre ID source et ID destination
• Stockée dans une table dédiée
• Permet de relancer une tâche en « update »
• Permet les « rollbacks »
• Permet les références entre contenus
30
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
SRC
SRC_ID
SRC_1
SRC_2
SRC_3
DEST
DEST_ID
DEST_1
DEST_2
DEST_3Transfo.
Transfo.
MAPMAPID Src 1 ID Dest 1
ID Src 2 ID Dest 2
Map
31
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Map
32
$this->map = new MigrateSQLMap($this->machineName, array( 'id' => array( 'type' => 'int', 'unsigned' => TRUE, 'description' => 'Content ID', ) ), MigrateDestinationNode::getKeySchema());
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Anatomie d’une tâche
• En résumé :
• Source
• Destination
• Mapping
• Map
33
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
• 1 Migration = 1 Classe PHP
• Doit étendre Migration
• Configuration de
• Source, Destination, Field Mapping, Map
• Effectuée dans __construct()
Migration
34
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Migration
• Offre des points d’entrée pour
• Altérer les données en lecture
• prepareRow($row)
• Altérer les entités en écriture
• prepare($entity, $row)
• Possibilité d’héritage
• Mutualisation de configuration
35
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Lancement des tâches
• Pour lancer les tâches
• Ligne de commande
• Drush
• Interface graphique
• Disponible dans le BackOffice
36
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Lancement des tâches
• Drush
• Différentes commandes : mi, ms, mr, mrs
• Paramètres intéressants :
• «limit» : permet de limiter le nombre d’éléments à importer (ou le temps d’import)
• «feedback» : notifications de l’avancement
37
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Lancement tâches
38
$ drush ms Name Total Imported Unimported Status Last imported LyonMetroLigneTypes 4 4 0 Idle 2012-05-23 13:49:35 LyonMetroLignes 154 154 0 Idle 2012-05-23 14:08:29 LyonMetroArrets 4036 4036 0 Idle 2012-05-23 13:58:16
$ drush mi LyonMetroLignes --update --feedback="50 items"Processed 50 (0 created, 50 updated, 0 failed, 0 ignored) in 1.4 sec (2156/min) - continuing with 'LyonMetroLignes' Processed 50 (0 created, 50 updated, 0 failed, 0 ignored) in 1.9 sec (1566/min) - continuing with 'LyonMetroLignes'Processed 50 (0 created, 50 updated, 0 failed, 0 ignored) in 2.2 sec (1377/min) - continuing with 'LyonMetroLignes'Processed 4 (0 created, 4 updated, 0 failed, 0 ignored) in 0.3 sec (899/min) - done with 'LyonMetroLignes'
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Lancement tâches
39
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
En pratique...
40
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Gestion des références entre contenus
41
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Références entre contenus• Prérequis
• Mécanisme de dépendances entre tâches
• Si B est dépendant de A
• La tâche A devra être lancée avant la tâche B
$this->dependencies = array('MigrationA');
42
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Références entre contenus• Tables ‘Map’
• Correspondances entre ID src. & dest.
• Permet à Migrate de gérer les références
• Dans le mapping :
$this->addFieldMapping('field_a_dest', 'field_a_src') ->sourceMigration('MigrationA');
43
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Références entre contenus• Lors de l’import de ce champ dans B :
• L’Id source va être « converti » en Id Destination en utilisant la table Map de la Migration A
• C’est l’Id « converti » qui sera enregistré dans le contenu
44
SELECT destid1 /* nid/tid/uid/fid */FROM migrate_map_A /* Map table for ‘A‘ */WHERE sourceid1 = :id_src /* id in ‘A’ src table */
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
• Import de A
Références entre contenus
45
SRC_A
SRC_ID
...
MAP_AMAP_A1023 378
1029 379
... ...
NODE
NID
...
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Références entre contenus
46
SRC_B
SRC_ID
A_ID
MAP_BMAP_B4204 455
4605 456
... ...
NODE_B
NID
A_REF
MAP_AMAP_A1023 378
1029 379
... ...
• Import de B
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
En pratique...
47
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Stratégies d’optimisation
48
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Requêtage• Comme dans tout import, le requêtage est
essentiel
• Limiter le nombre de requêtes
• Eviter de faire une requête pour chaque ligne source
• INNER JOIN / LEFT JOIN /...
• Optimiser la source (si possible)
• ajout d’indexes
• configuration DB (innodb_buffer_pool_size,...)49
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Modules « gourmands »
• Désactivation de traitements lors de l’import
• Pathauto : il faut mieux construire l’url « à la main »
• ‘migrate_extras’ fournit un moyen de le désactiver pour une migration donnée
50
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Highwater Field• Pour les imports réguliers
• N’importer que les données mises à jour depuis le dernier import
$this->highwaterField = array( 'name' => 'last_changed', 'alias' => 'w', 'type' => 'int',);
$query->orderBy('last_changed');
51
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Highwater Field
• Avec le Highwater Field
• Migrate ajoutera automatiquement une condition sur la requête source
• Restriction des enregistrements sources à traiter
• Ne fonctionne automatiquement que pour les sources : SQL, Oracle & MSSQL
52
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
preImport()
• En cas de structure de base trop « tordue »
• On peut être amené à faire une première passe pour charger des éléments en mémoire
• Ces éléments seront réinjectés dans chaque contenu cible
• Pour cela on peut utilise la méthode preImport()
53
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
// Called once during the migration processpublic function preImport() { parent::preImport(); $query = Database::getConnection('myDB') ->select('metas', 'm'); $query->fields('m', array( 'id_doc', 'id_meta', 'valeur'));
/* ... */ $result = $query->execute(); while ($row = $result->fetchObject()) {
if ($row->id_meta == self::ID_META_TITRE) { $this->metas[$row->id_doc]['titre'] = $row->valeur; } if ($row->id_meta == self::ID_META_DATE) { $this->metas[$row->id_doc]['date'] = $row->valeur; } }}
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
// Called for each source rowpublic function prepareRow($row) { if (isset($this->metas[$row->id_doc]['titre'])) { $row->titre = $this->metas[$row->id_doc]['titre']; }
if (isset($this->metas[$row->id_doc]['date'])) { $row->titre = $this->metas[$row->id_doc]['date']; } return parent::prepareRow($row);}
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
En cas de besoin• Attention à la mémoire
• On peut être amené à ajuster la memory_limit
• Séparation en 2 migrations
• Utilisation de «system of record»
• Seuls les champs «mappés» seront écrasés
56
$this->systemOfRecord = Migration::DESTINATION;
Drupal Camp Lyon - Optimisez vos imports de données avec MigrateMatthieu Guillermin - Mai 2012
Des questions ?
57
Merci pour votre attention !@mguillermin
Recommended