Cómo volver a ejecutar hook_post_update_NAME ()

Respuestas:

11

Los ganchos "post_update" que se han ejecutado se almacenan en la base de datos, en la key_valuetabla, post_updatecolección, pero los datos se serializan y son difíciles de actualizar directamente.

Utilicé algunos de los detalles de la respuesta de @ kiamlaluno para crear un script drush que puedes usar para restablecer un solo gancho. Aquí hay una versión básica (la versión más larga está aquí ):

#!/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");
}

Y aquí hay un ejemplo de cómo se ve cuando lo ejecuta desde la línea de comandos:

./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
fuente
3
¿Has pensado en contribuir de nuevo a drush, github.com/drush-ops/drush ?
powpow12
1
Esta es una característica bastante dulce, pero es demasiado nicho para Core Drush. Quizás alguien haga un archivo de comando para ello.
moshe weitzman
3

Aquí hay un ejemplo que puede usar desde la línea de comandos con 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);'

Cuando vuelva a ejecutar drush updatedb, verá su post_update_hook esperando a ser ejecutado.

Jason Yarrington
fuente
Esto funcionó bien para mí, solo para mencionar que en drush 9, esdrush php:eval 'command'
powpow12
Muy útil, si está en un entorno de solo lectura. Muchas gracias;)
Mirsoft
1

UpdateRegistry::getPendingUpdateFunctions()contiene el siguiente código. Mira lo que dice el comentario.

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

UpdateRegistry :: $ updateType está establecido en 'post_update'.
$this->keyValuese ajusta desde UpdateRegistryFactory::create()el valor de $this->container->get('keyvalue')->get('post_update').

El código de procedimiento equivalente para obtener esa colección keyvalue es el siguiente.

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

Establezca existente_updates en una matriz vacía, y Drupal pensará que no se ha llamado a ninguna de las devoluciones de llamada posteriores a la actualización.

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

Elimine el nombre de devolución de llamada de la clave existente_actualizaciones de ese valor clave, y Drupal pensará que aún no se ha invocado la devolución de llamada posterior a la actualización.

kiamlaluno
fuente
0

Llámalo desde adentro hook_update_n()y luego haz lo que estabas haciendo antes.

nvahalik
fuente
1
Eso no parece una buena idea, ya que el propósito completo del mecanismo hook_post_update es tener un Drupal completamente funcional disponible después de que se hayan ejecutado todas las actualizaciones. Fue introducido porque no hay garantías sobre el estado de Drupal durante las actualizaciones.
Eelke Blok