Migrar: Qual é a diferença entre prepare () e prepareRow ()?

8

Usando o módulo Migrate: Entendo que prepareRow () executa um filtro na linha e deve retornar TRUE ou FALSE com base em algumas condições, o que permite que uma linha seja migrada ou não, mas alguém poderia esclarecer:

  • quando usar prepare ()
  • quando usar prepareRow ()
  • por que você não adicionou um filtro na consulta sql inicial para filtrar os resultados da linha que você pode remover / incluir em qualquer uma das opções acima

Obrigado!

user4984
fonte
11
Um motivo para não filtrar na consulta sql é adicionar um mapeamento para as linhas que você decide ignorar. Por exemplo, estou importando usuários para um site existente. Desejo pular usuários que já existem no destino e adicionar um mapeamento como se o usuário tivesse realmente sido importado , para que outras migrações, dependendo disso, funcionem de maneira inadequada.
jonhattan 13/09/16

Respostas:

9

Tudo isso é abordado em profundidade na documentação das classes de Migrações fornecida pelo projeto. Especificamente na página de métodos de Migração comum implementada , que diz o seguinte e inclui outras implementações simples de funções de exemplo. Dos documentos ...

função prepare_row ($ row)

O método prepareRow () é chamado pelo método next () da classe de origem, após carregar a linha de dados. O argumento $ row é um objeto stdClass que contém os dados brutos, conforme fornecido pela fonte. Há dois motivos principais para implementar o prepareRow ():

  1. Para modificar a linha de dados antes que ela passe por outros métodos e manipuladores: por exemplo, buscando dados relacionados, dividindo os campos de origem, combinando ou criando novos campos de origem com base em alguma lógica.
  2. Para pular uma linha condicionalmente (retornando FALSE).

função prepare ($ entity, stdClass $ row)

O método prepare () da classe Migration é chamado pelo método prepare () da classe de destino, depois de chamar todos os métodos prepare () em nível de campo e imediatamente antes de o objeto de destino ser salvo. O argumento $ entity é o objeto de destino, conforme preenchido pelos mapeamentos de campo iniciais e manipulado pelos métodos em nível de campo; o argumento $ row é um objeto que contém os dados após prepareRow () e qualquer retorno de chamada foi aplicado. O método prepare () é a última chance de manipular o objeto de destino antes de ser salvo no banco de dados Drupal. É importante lembrar que, como é chamado após os manipuladores de campo, os campos estarão em suas formas totalmente expandidas (ou seja, no Drupal 7, o valor do campo de texto estará em $entity->field_textual_data['und'][0]['value']vez de simplesmente $entity->field_textual_data).

O módulo Migrar é uma estrutura que permite encapsular um processo de migração de uma parte dos dados de origem para um local e configuração de destino. Uma migração consiste em:

  • definir onde os dados estão
  • definir para onde os dados devem ir
  • buscar um pedaço de dados (linha)
  • higienizar os dados
  • começar a mover os dados (digamos, para uma entidade)
  • realmente mover os dados
  • depois de mover os dados, execute ações adicionais

A API fornece ganchos para afetar os dados que estão sendo movidos neste ciclo de vida de uma migração. Ao excluir dados da migração por meio de sua consulta inicial, você limita o controle que você tem sobre o total de dados que pode mover. Para sub-migrações, você pode achar isso útil. Mas em uma migração geral de conteúdo, você deseja que sua migração seja o mais abrangente possível.

tenken
fonte
Obrigado tenken, exatamente o que eu estava procurando. Aprecie os pensamentos sobre a remoção de elementos da consulta inicial também.
user4984
6

Se você pode selecionar a linha correta, escrevendo-a em uma consulta, vá em frente, no entanto preprareRow () pode ser usado em sistemas mais complexos, onde vários parâmetros podem ser necessários antes da linha ser migrada. Nesse caso, é mais fácil percorrer todas as linhas e executar a lógica por linha.

prepare () é executado após prepareRow () e é sua última chance de alterar a entidade antes de ser salva no banco de dados.

Mais informações sobre isso podem ser encontradas aqui: https://www.drupal.org/node/1132582

Neograph734
fonte
Eu encontrei esta concisa para ser e compreensível
Johnathan Elmore
3

Esta é uma resposta parcial e de forma alguma completa. Eu também gostaria de descobrir mais sobre os dois. Portanto, isso pode ser parte de uma discussão; embora eu tenha escrito como resposta em vez de comentar por causa dos seguintes trechos de código e exemplos de como usei as classes acima.

Deixe-me ilustrar alguns dos meus usos prepareRow () como - que faz o que diz.

Recentemente, eu estava fornecendo alguns dados para importar de um banco de dados não drupal. A entidade à qual estou adicionando exige a inserção de campos que não tenho na minha importação de dados.

Então, antes que minha classe de origem seja criada, posso adicionar

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

e então na função prepareRow eu posso fazer o seguinte

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

você também pode executar as instruções if / else do php aqui, se necessário.

Eu também usei a função de preparação no meu código e estou usando-a para atribuir valores à entidade.

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

Eu só precisei usar isso nesse cenário, pois fiz meu próprio plug-in de nó personalizado.

Além disso, se você precisar fazer cálculos sobre isso, poderá fazê-lo em prepareRow, que é executado antes de prepare ()

Por exemplo, na importação, eu tinha um valor chamado 'Cidade' - e poderia transformá-lo em um ID do termo.

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

Eu espero que isso ajude.

DJ
fonte