引入了hook_post_update_NAME()
Drupal 8 ,它在hook_update_n
更新模块方面比拥有一些优势。
每个hook_post_update_NAME()
都只能运行一次,但是有时我想重新运行它,例如在开发过程中调试更新挂钩时。使用hook_update_n
,您可以在数据库中重置架构版本。
您如何重新运行hook_post_update_NAME()
?
引入了hook_post_update_NAME()
Drupal 8 ,它在hook_update_n
更新模块方面比拥有一些优势。
每个hook_post_update_NAME()
都只能运行一次,但是有时我想重新运行它,例如在开发过程中调试更新挂钩时。使用hook_update_n
,您可以在数据库中重置架构版本。
您如何重新运行hook_post_update_NAME()
?
Answers:
已运行的“ post_update”钩子存储在数据库的key_value
表post_update
集合中,但是数据已序列化并且难以直接更新。
我使用了@kiamlaluno的答案中的一些细节来创建绘制脚本,您可以使用该脚本重置单个钩子。这是基本版本(此处是更长的版本):
#!/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
这是您可以在命令行中使用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 php:eval 'command'
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');
将existing_updates设置为一个空数组,Drupal会认为没有任何更新后回调被调用。
$key_value = \Drupal::keyValue('post_update');
$key_value->set('existing_updates', []);
从该键值的existing_updates键中删除该回调名称,Drupal会认为尚未调用更新后回调。
从内部调用它hook_update_n()
,然后执行之前的操作。