Как перезапустить hook_post_update_NAME ()


11

Представленhook_post_update_NAME() Drupal 8, который имеет некоторые преимущества поhook_update_n обновлению модулей.

Каждый hook_post_update_NAME()должен запускаться только один раз, но иногда я хочу его перезапустить, например, когда я отлаживаю хук обновления во время разработки. С помощью hook_update_nвы можете сбросить версию схемы в базе данных .

Как вы перезапустите hook_post_update_NAME()?

Ответы:


11

Выполненные перехваты post_update хранятся в базе данных, в key_valueтаблице, post_updateколлекции, но данные сериализуются и неудобны для непосредственного обновления.

Я использовал некоторые детали из ответа @ kiamlaluno, чтобы создать сценарий drush, который можно использовать для сброса одного хука. Вот базовая версия ( более длинная версия здесь ):

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

И вот пример того, как это выглядит, когда вы запускаете его из командной строки:

./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

3
Вы думали о том, чтобы внести это обратно в drush, github.com/drush-ops/drush ?
powpow12

1
Это довольно приятная особенность, но она слишком ниша для ядра Drush. Возможно, кто-то сделает командный файл для этого.
Моше Вейцман

3

Вот пример, который вы можете использовать из командной строки с помощью 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);'

При повторном запуске drush updatedb вы увидите, что ваш post_update_hook ожидает запуска.


Это хорошо сработало для меня, просто упомяну, что в Drush 9 этоdrush php:eval 'command'
powpow12

Очень полезно, если в среде только для чтения. Большое спасибо;)
Мирсофт

1

UpdateRegistry::getPendingUpdateFunctions()содержит следующий код Посмотрите, что говорится в комментарии.

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

UpdateRegistry :: $ updateType установлен в 'post_update'.
$this->keyValueустанавливается UpdateRegistryFactory::create()со значением $this->container->get('keyvalue')->get('post_update').

Эквивалентный процедурный код для получения этой коллекции значений ключей следующий.

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

Задайте для существующих_updates пустой массив, и Drupal будет думать, что ни один из обратных вызовов после обновления не был вызван.

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

Удалите имя обратного вызова из существующего ключа этого значения ключа, и Drupal будет думать, что обратный вызов после обновления еще не был вызван.


0

Позвони изнутри hook_update_n()и сделай то, что делал раньше.


1
Это не очень хорошая идея, так как основная цель механизма hook_post_update - иметь полностью функциональный Drupal, доступный после запуска всех обновлений. Это было введено, потому что нет никаких гарантий о состоянии Drupal во время обновлений.
Eelke Blok
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.