Como executar novamente hook_post_update_NAME ()

11

Foi introduzido ohook_post_update_NAME() Drupal 8, que traz alguns benefícioshook_update_n para a atualização de módulos.

Cada um hook_post_update_NAME()deve ser executado apenas uma vez, mas às vezes quero executá-lo novamente, como quando estou depurando o gancho de atualização durante o desenvolvimento. Com hook_update_n, você pode redefinir a versão do esquema no banco de dados .

Como você executa novamente hook_post_update_NAME()?

bryanbraun
fonte

Respostas:

11

Os ganchos "post_update" que foram executados são armazenados no banco de dados, na key_valuetabela, post_updatecoleção, mas os dados são serializados e difíceis de atualizar diretamente.

Eu usei alguns detalhes da resposta de @ kiamlaluno para criar um script drush que você pode usar para redefinir um único gancho. Aqui está uma versão básica (a versão mais longa está aqui ):

#!/usr/bin/env drush

$key_value = \Drupal::keyValue('post_update');
$update_list = $key_value->get('existing_updates');

$choice = drush_choice($update_list, dt('Which post_update hook do you want to reset?'));

if ($choice) {
  $removed_el = $update_list[$choice];
  unset($update_list[$choice]);
  $key_value->set('existing_updates', $update_list);
  drush_print("$removed_el was reset");
} else {
  drush_print("Reset was cancelled");
}

E aqui está um exemplo de como é quando você o executa na linha de comando:

./scripts/reset_hook_post_update_NAME.drush

Which post_update hook do you want to reset?
 [0]   :  Cancel
 [1]   :  system_post_update_add_region_to_entity_displays
 [2]   :  system_post_update_hashes_clear_cache
 [3]   :  system_post_update_recalculate_configuration_entity_dependencies
 [4]   :  system_post_update_timestamp_plugins
 [5]   :  my_module_post_update_example_hook

# The script pauses for user input. 
5 

my_module_post_update_example_hook was reset
bryanbraun
fonte
3
você já pensou em contribuir com isso de volta ao drush, github.com/drush-ops/drush ?
powpow12
11
Este é um recurso bastante interessante, mas é um nicho um pouco demais para o Core Drush. Talvez alguém crie um arquivo de comando para ele.
Moshe weitzman # 9/18
3

Aqui está um exemplo que você pode usar na linha de comando com drush php-eval:

drush php-eval -e '$update_hook_name = "<my_hook_post_update_name>";
$key_value = \Drupal::keyValue('post_update');
$existing_updates = $key_value->get('existing_updates');
$index = array_search($update_hook_name,$existing_updates); 
unset($existing_updates[$index]);
$key_value->set('existing_updates', $existing_updates);'

Quando você executar novamente o drush updatedb, verá seu post_update_hook aguardando a execução.

Jason Yarrington
fonte
Isso funcionou bem para mim, só para mencionar que em Drush 9, édrush php:eval 'command'
powpow12
Muito útil, se em ambiente somente leitura. Muito obrigado;)
Mirsoft
1

UpdateRegistry::getPendingUpdateFunctions()contém o seguinte código. Veja o que o comentário diz.

  // First figure out which hook_{$this->updateType}_NAME got executed
  // already.
  $existing_update_functions = $this->keyValue->get('existing_updates', []);

UpdateRegistry :: $ updateType está definido como 'post_update'.
$this->keyValueé definido de UpdateRegistryFactory::create()com o valor de $this->container->get('keyvalue')->get('post_update').

O código de procedimento equivalente para obter essa coleção de valores-chave é o seguinte.

$key_value = \Drupal::keyValue('post_update');

Defina existir_updates para uma matriz vazia e o Drupal pensará que nenhum dos retornos de chamada pós-atualização foram chamados.

$key_value = \Drupal::keyValue('post_update');
$key_value->set('existing_updates', []);

Remova o nome do retorno de chamada da chave existente_updates desse valor-chave e o Drupal pensará que o retorno de chamada pós-atualização ainda não foi invocado.

kiamlaluno
fonte
0

Ligue de dentro hook_update_n()e faça o que estava fazendo antes.

nvahalik
fonte
11
Isso não parece uma boa ideia, já que todo o objetivo do mecanismo hook_post_update é ter um Drupal totalmente funcional disponível após a execução de todas as atualizações. Foi introduzido porque não há garantias sobre o estado do Drupal durante as atualizações.
Eelke Blok