Как при обновлении версии модуля создать таблицу в базе данных

Вот столкнулся с задачей: есть модуль, к которому необходимо написать обновление так, чтобы в следующей версии была добавлена новая таблица в базе данных. Drupal, как обычно, не подкачал и даже порадовал готовой функцией.

Обновление модуля осуществляется через .install файл. Для начала необходимо в hook_schema() описать таблицу. Например, вот так:

  1. /**
  2.  * Implements hook_schema().
  3.  */
  4. function MY_MODULE_schema() {
  5. $schema = array();
  6.  
  7. $schema['new_table'] = array(
  8. 'description' => 'Stores information about Instagram accounts, categories, node relations.',
  9. 'fields' => array(
  10. 'aid' => array(
  11. 'type' => 'serial',
  12. 'unsigned' => TRUE,
  13. 'not null' => TRUE,
  14. 'description' => 'Account ID.',
  15. ),
  16. 'username' => array(
  17. 'type' => 'varchar',
  18. 'length' => 64,
  19. 'not null' => TRUE,
  20. 'default' => '',
  21. 'description' => 'Instagram account username.',
  22. ),
  23. 'entity_type' => array(
  24. 'type' => 'varchar',
  25. 'length' => 32,
  26. 'not null' => TRUE,
  27. 'default' => '',
  28. 'description' => 'Entity type to which Instagram account attached.',
  29. ),
  30. 'entity_id' => array(
  31. 'type' => 'int',
  32. 'not null' => TRUE,
  33. 'default' => 0,
  34. 'description' => 'Entity id to which Instagram account attached.',
  35. ),
  36. ),
  37. 'primary key' => array('aid'),
  38. );
  39.  
  40. return $schema;
  41. }
Обновления для модуля указываются в имплементации хука hook_update_N(). Логика обновлений довольно простая:
  • версия любого модуля хранится в таблице system базы данных;
  • при запуске обновления (через update.php, например), Drupal обрабатывает все hook_update_N() и, если находит имплементации, где N больше версии, хранящейся в БД, запускает обновление;
  • если же модуль устанавливается с нуля, то hook_update_N() не запускается, хоть в таблице system и устанавливается самая последняя версия - необходимо это учитывать при разработке.

Итак, пусть это будет первым обновлением для нашего модуля. Тогда код функции будет выглядеть так:

  1. /**
  2.  * Implements hook_update_N().
  3.  */
  4. function MU_MODULE_update_7100() {
  5. $instagram_tables = drupal_get_schema_unprocessed('MY_MODULE');
  6. foreach ($instagram_tables as $name => $table) {
  7. db_create_table($name, $table);
  8. }
  9. }

Функиця drupal_get_schema_unprocessed() возвращает информацию о еще не созданных таблицах, описанных в указанном модуле. Обратите внимание, что приведенный код также обработает случай, когда таблиц будет несколько.

Вот такое быстрое и красивое решение на случай обновления модулей.

Комментарии

Аватар пользователя xandeadx
xandeadx

Плохой тон в hook_update_N использовать данные из hook_schema - schema может измениться, что поломает логику обновлений. Правильно делать так:


/**
* Implements hook_update_N().
*/
function MU_MODULE_update_7100() {
db_create_table('new_table', array(/* копи-паст из hook_schema */));
}

Аватар пользователя xandeadx
xandeadx

ну и плюс нумерацию апдейтов начинается с 1.
7100 это для модулей, который мигрируют с прошлой мажорной версии.

Аватар пользователя angarsky
angarsky
Если модуль разрабатывается в ветке 7.x-1.x, то версии обновления будут 7100, 7101, 7102 и т.д. - я такой логике следовал при написании.

Добавить комментарий

 888     888   .d8888b.                      
888 888 d88P Y88b
888 888 888 888
Y88b d88P 888 .d8888b 888 888
Y88b d88P 888 88K 888 888
Y88o88P 888 888 "Y8888b. 888 888
Y888P Y88b d88P X88 Y88b 888
Y8P "Y8888P" 88888P' "Y88888
888
Y8b d88P
"Y88P"
Зарегистрируйтесь для добавления материалов без проверки.