Migrar: ¿Cuál es la diferencia entre prepare () y prepareRow ()?

8

Usando el módulo Migrate: entiendo que prepareRow () ejecuta un filtro en la fila y debe devolver VERDADERO o FALSO en función de algunas condiciones, lo que permite migrar una fila o no, pero alguien podría aclarar:

  • cuándo usar prepare ()
  • cuándo usar prepareRow ()
  • por qué no agregaría un filtro en la consulta sql inicial para filtrar los resultados de fila que podría eliminar / incluir en cualquiera de los anteriores

¡Gracias!

usuario4984
fuente
1
Una razón para no filtrar en la consulta sql es agregar una asignación para las filas que decide omitir. Por ejemplo, estoy importando usuarios a un sitio existente. Quiero omitir los usuarios que ya existen en el destino y quiero agregar una asignación como si el usuario realmente se hubiera importado , por lo que otras migraciones que dependen de esto funcionan de manera suave.
jonhattan

Respuestas:

9

Todo esto está cubierto en profundidad en la documentación de las clases de Migraciones proporcionada por el proyecto. Específicamente en la página de métodos de migración implementados comúnmente que dice lo siguiente e incluye implementaciones de funciones de ejemplo simples adicionales. De los documentos ...

función prepare_row ($ fila)

El método prepareRow () es llamado por el método next () de la clase fuente, después de cargar la fila de datos. El argumento $ row es un objeto stdClass que contiene los datos sin procesar proporcionados por la fuente. Hay dos razones principales para implementar prepareRow ():

  1. Para modificar la fila de datos antes de que pase por otros métodos y controladores: por ejemplo, obtener datos relacionados, dividir campos de origen, combinar o crear nuevos campos de origen basados ​​en alguna lógica.
  2. Para saltear una fila condicionalmente (devolviendo FALSE).

función preparar ($ entidad, stdClass $ fila)

El método prepare () de la clase de migración se llama mediante el método prepare () de la clase de destino, después de haber llamado a todos los métodos prepare () de nivel de campo e inmediatamente antes de que se guarde el objeto de destino. El argumento $ entity es el objeto de destino tal como se rellena con las asignaciones de campo iniciales y se manipula con los métodos de nivel de campo; El argumento $ row es un objeto que contiene los datos después de prepareRow () y se han aplicado las devoluciones de llamada. El método prepare () es la última oportunidad para manipular el objeto de destino antes de guardarlo en la base de datos de Drupal. Es importante recordar que, dado que se llama después de los manejadores de campo, los campos estarán en sus formas completamente expandidas (es decir, en Drupal 7 un valor de campo de texto será en $entity->field_textual_data['und'][0]['value']lugar de simplemente $entity->field_textual_data).

El módulo Migrate es un marco que le permite encapsular un proceso de migración desde un dato de origen a una ubicación y configuración de destino. Una migración consiste en:

  • definir dónde están los datos
  • definir dónde deben ir los datos
  • buscar una pieza de datos (fila)
  • desinfectar los datos
  • comenzar a mover los datos (digamos en una entidad)
  • en realidad mover los datos
  • después de mover los datos, realice acciones adicionales

La API proporciona enlaces para afectar los datos que se mueven en este ciclo de vida de una migración. Al excluir los datos de la migración a través de su consulta inicial, está limitando la cantidad de control que tiene sobre el total de datos que podría mover. Para las submigraciones, puede resultarle útil. Pero en una migración de contenido general, desearía que su migración fuera lo más completa posible.

Tenken
fuente
Gracias Tenken, exactamente lo que estaba buscando. Aprecie los pensamientos sobre eliminar elementos de la consulta inicial también.
user4984
6

Si puede seleccionar la fila correcta escribiéndola en una consulta, hágalo, sin embargo, preprareRow () se puede usar en sistemas más complejos donde se pueden requerir varios parámetros antes de migrar la fila. En tal caso, es más fácil ejecutar todas las filas y hacer la lógica por filas.

prepare () se ejecuta después de prepareRow () y es su última oportunidad de alterar la entidad antes de que se guarde en la base de datos.

Puede encontrar más información sobre esto aquí: https://www.drupal.org/node/1132582

Neograph734
fuente
Encontré que esto es conciso y comprensible
Johnathan Elmore
3

Esta es una respuesta parcial y de ninguna manera completa. También me gustaría saber más sobre ambos. Entonces esto puede ser parte de una discusión; aunque he escrito como respuesta en lugar de comentar debido a los siguientes fragmentos de código y ejemplos de cómo he usado las clases anteriores.

Permítanme ilustrar algunos de mis usos prepareRow () como, que hace lo que dice.

Hace poco estaba dando algunos datos para importar desde una base de datos no drupal. La entidad a la que estoy agregando requiere que se ingresen campos que no tengo en mi importación de datos.

Entonces, antes de crear mi clase fuente, puedo agregar

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

y luego en la función prepareRow puedo hacer lo siguiente

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

También puede ejecutar php if / else declaraciones aquí si es necesario.

También he usado la función de preparación en mi código y la estoy usando para asignar valores a la entidad.

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

Solo tuve que usar esto en este escenario ya que hice mi propio complemento de nodo personalizado.

Además, si necesita hacer cálculos al respecto, puede hacerlo en prepareRow, que se ejecuta antes de prepare ()

Por ejemplo, en la importación tenía un valor etiquetado como 'Ciudad', y podría convertirlo en un Id. De término.

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

Espero que esto ayude.

Deejay
fuente