Migrer: quelle est la différence entre prepare () et prepareRow ()?

8

Utilisation du module Migrate: je comprends que prepareRow () exécute un filtre sur la ligne et devrait retourner VRAI ou FAUX en fonction de certaines conditions, ce qui permet de migrer une ligne ou non, mais quelqu'un pourrait-il clarifier:

  • quand utiliser prepare ()
  • quand utiliser prepareRow ()
  • pourquoi vous n'ajouteriez pas de filtre dans la requête sql initiale pour filtrer les résultats de ligne que vous pourriez supprimer / inclure dans l'une des options ci-dessus

Merci!

user4984
la source
1
Une raison pour ne pas filtrer la requête SQL est d'ajouter un mappage pour les lignes que vous décidez d'ignorer. Par exemple, j'importe des utilisateurs sur un site existant. Je veux ignorer les utilisateurs qui existent déjà sur la destination, et je veux ajouter un mappage comme si l'utilisateur était réellement importé , de sorte que les autres migrations en fonction de cela fonctionnent correctement.
jonhattan

Réponses:

9

Tout cela est traité en détail dans la documentation des classes de migrations fournie par le projet. Plus précisément dans la page des méthodes de migration mises en œuvre en commun qui indique ce qui suit et inclut d'autres exemples d'implémentations de fonctions simples. De la documentation ...

fonction prepare_row ($ row)

La méthode prepareRow () est appelée par la méthode next () de la classe source, après le chargement de la ligne de données. L'argument $ row est un objet stdClass contenant les données brutes fournies par la source. Il existe deux raisons principales pour implémenter prepareRow ():

  1. Pour modifier la ligne de données avant de passer par d'autres méthodes et gestionnaires: par exemple, récupérer des données associées, fractionner des champs source, combiner ou créer de nouveaux champs source en fonction d'une logique.
  2. Pour sauter conditionnellement une ligne (en renvoyant FALSE).

fonction prepare ($ entity, stdClass $ row)

La méthode Migration class prepare () est appelée par la méthode de destination class prepare (), après avoir appelé toutes les méthodes prepare () au niveau du champ et immédiatement avant l'enregistrement de l'objet de destination. L'argument $ entity est l'objet de destination tel qu'il est rempli par les mappages de champs initiaux et manipulé par les méthodes au niveau des champs; l'argument $ row est un objet contenant les données après prepareRow () et tous les rappels ont été appliqués. La méthode prepare () est la dernière chance de manipuler l'objet de destination avant qu'il ne soit enregistré dans la base de données Drupal. Il est important de se rappeler que, comme il est appelé après les gestionnaires de champs, les champs seront dans leurs formes entièrement développées (c'est-à-dire que dans Drupal 7 une valeur de champ de texte sera $entity->field_textual_data['und'][0]['value']plutôt que simplement $entity->field_textual_data).

Le module Migrate est une infrastructure qui vous permet d'encapsuler un processus de migration d'une donnée source vers un emplacement et une configuration de destination. Une migration consiste en:

  • définir où se trouvent les données
  • définir où les données doivent aller
  • récupérer une donnée (ligne)
  • assainir les données
  • commencer à déplacer les données (par exemple dans une entité)
  • déplacer réellement les données
  • après avoir déplacé les données, effectuez des actions supplémentaires

L'API fournit des crochets pour affecter les données déplacées dans ce cycle de vie d'une migration. En excluant les données de la migration via votre requête initiale, vous limitez le contrôle que vous avez sur le total des données que vous pouvez déplacer. Pour les sous-migrations, cela peut vous être utile. Mais dans une migration de contenu générale, vous voudriez que votre migration soit aussi globale que possible.

tenken
la source
Merci tenken, exactement ce que je cherchais. Appréciez également les réflexions sur la suppression d'éléments de la requête initiale.
user4984
6

Si vous pouvez sélectionner la bonne ligne en l'écrivant dans une requête, allez-y, cependant preprareRow () peut être utilisé dans des systèmes plus complexes où plusieurs paramètres peuvent être requis avant la migration de la ligne. Dans un tel cas, il est plus facile de parcourir toutes les lignes et de faire la logique ligne par ligne.

prepare () est exécuté après prepareRow () et est votre dernière chance de modifier l'entité avant qu'elle ne soit enregistrée dans la base de données.

Vous trouverez plus d'informations à ce sujet ici: https://www.drupal.org/node/1132582

Neograph734
la source
J'ai trouvé que c'était concis et compréhensible
Johnathan Elmore
3

Ceci est une réponse partielle et nullement complète. Je voudrais également en savoir plus sur ces deux éléments. Cela peut donc faire partie d'une discussion; bien que j'aie écrit comme réponse plutôt que comme commentaire à cause des extraits de code suivants et des exemples de la façon dont j'ai utilisé les classes ci-dessus.

Permettez-moi d'illustrer certaines de mes utilisations prepareRow () as - qui fait ce qu'il dit.

Récemment, je donnais des données à importer à partir d'une base de données non drupale. L'entité à laquelle j'ajoute nécessite la saisie de champs que je n'ai pas dans mon importation de données.

Donc, avant que ma classe source soit créée, je peux ajouter

  $source_fields = array(
    'changed' => t('Timestamp of when the change was made.'),
    'created' => t('Timestamp of when the node was Created.'),
 );

puis dans la fonction prepareRow, je peux faire ce qui suit

$nowtimestamp = mktime(date('Y-m-d'));
$row->changed = $nowtimestamp;
$row->created = $nowtimestamp;

vous pouvez également exécuter les instructions php if / else ici si nécessaire.

J'ai également utilisé la fonction prepare dans mon code et je l'utilise pour attribuer des valeurs à l'entité.

$account->field_job_location [und][0]['tid'] = $row->job_location_tid;

Je n'ai eu qu'à l'utiliser dans ce scénario car j'ai créé mon propre plugin de nœud personnalisé.

De plus, si vous avez besoin de faire des calculs à ce sujet, vous pouvez le faire dans prepareRow qui s'exécute avant prepare ()

Par exemple, lors de l'importation, j'avais une valeur intitulée «Ville» - et je pouvais en faire un identifiant de terme.

 if ($TownCity == 'London' ){
            $row->job_location_tid = '10';
      } else {
        $row->job_location_tid = '11';
      } 

J'espère que ça aide.

Deejay
la source