Нужно ли создавать новые таблицы в 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']);
}

Вы имеете в виду, что нет другого способа, кроме как скопировать определение таблицы из 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 Наир
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.