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

Вот столкнулся с задачей: есть модуль, к которому необходимо написать обновление так, чтобы в следующей версии была добавлена новая таблица в базе данных. 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 и т.д. - я такой логике следовал при написании.

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

  .d888  8888888888  888           d8888  
d88P" 888 888 d8P888
888 888 888 d8P 888
888888 8888888 888 888 d8P 888
888 888 888 .88P d88 888
888 888 888888K 8888888888
888 888 888 "88b 888
888 888 888 888 888


Зарегистрируйтесь для добавления материалов без проверки.