Нужно ли создавать новые таблицы в hook_update_N ()?

11

Когда вы создаете новую таблицу в hook_schema(), должна ли эта таблица также добавляться в hook_update_N()? Или есть какой-то трюк или что-то, что я пропустил, чтобы databae-updates автоматически добавляли таблицы?

Документация о hook_update_N () ничего не объясняет о введении новых таблиц, тогда как документацияhook_schema() говорит:

Таблицы, объявленные этим хуком, будут автоматически созданы при первом включении модуля и удалены при удалении модуля.

(Изюминка моя)

И если да, то как лучше всего не дублировать определения схемы для новой таблицы как в hook_update_N (), так и в hook_schema (). Просто ссылаясь на схему следующим образом:

 function hook_update_N(&$sandbox) {
   $schema = hook_schema();
   $name = "foo";
   $table = $schema["foo"];
   db_create_table($name, $table);
 }

Кажется, работает, но при повторном изменении таблицы произойдет сбой, если пользователь запустит обновления и запустит два или более hook_update_N (). В конце концов: первый hook_update_N уже установит правильную базу данных, а второй hook_update_M () попытается добавить / изменить / изменить столбцы, которые уже были обновлены.

Как вы справляетесь с этим?

Беркеш
источник
Обратитесь к drupal.org/node/150215 для документации. Таким образом, добавить новую таблицу после установки модуля можно через hook_update_N, но вы также добавляете определение таблицы в hook_schema для новых пользователей или новых установок. Итак, подведите итог, если вы внесете какие-либо изменения в таблицу, чтобы обновить текущие таблицы с помощью hook_update_N, но вы также объедините изменения в hook_schema.
Джунедкази
1
Так что, похоже, нет способа избежать нарушения DRY. Жалость.
беркес
ничего, что я знаю. Но вы можете написать небольшую функцию, которая имеет определение схемы, и вызвать это определение в обеих функциях.
Джунедкази
@berkes Можно определить другую функцию, которая возвращает дополнительную схему и ссылается на нее как в хуках обновления, так и установки.
user1359

Ответы:

15

Так что просто скопируйте с сайта drupal.org. Вам также необходимо добавить определение схемы в hook_schema.

/**
 * Create new database table {mytable2}.
 */
function mymodule_update_7101() {
  $schema['mytable2'] = array(
     // table definition array goes here
  );
  db_create_table('mytable2', $schema['mytable2']);
}
junedkazi
источник
Вы имеете в виду, что нет другого способа, кроме как скопировать определение таблицы из hook_schema () в hook_update_N (). Другими словами: что нет способа избежать нарушения СУХОЙ?
беркес
3
@berkes точнее на ... есть очень хорошее объяснение, почему это здесь, если вы еще не видели его
Клайв
@Clive Это потрясающий пример. Никогда раньше не видел. +1
junedkazi
@junedkazi На эту ссылку есть ссылка, которую вы указали в своем комментарии;)
Клайв
-2

mymodule_update_7101 () хорош, вместе с этим хуком, если мы добавим hook_install () для выполнения того же самого, в то время как установка модуля вместо определения hook_schema () также работает для меня.


/**
 * Implements hook_install().
 */
function mymodule_install() {
  // Change the update number accordingly for more updates.
  for ($i = 7101; $i < 7102; $i++) {
    $update_func = 'mymodule_update_' . $i;
    if (function_exists($update_func)) {
      $update_func();
    }
  }
}

Ахила В Наир
источник
В Drupal гораздо лучше использовать API в соответствии с указаниями. Используйте hook_schema () и hook_update_N () напрямую. Одна вещь, которую я делаю, это вызывает реализацию моего модуля hook_schema в hook_update_N (), а затем запускает соответствующие функции db_ *.
Мрадклифф
hook_install()не должен вызывать какие-либо реализации hook_update_N () по простому факту: hook_install()предназначен для установки модуля в первый раз, что означает отсутствие таблиц для обновления. Кроме того, ваш код не будет работать для обновлений, для запуска которых требуется пакет.
kiamlaluno
Этот фрагмент кода будет полезен, если вы обновляете схему и только для целей развертывания. Для существующей действующей системы это не может быть использовано.
Ахила V Наир