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

Вот столкнулся с задачей: есть модуль, к которому необходимо написать обновление так, чтобы в следующей версии была добавлена новая таблица в базе данных. 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       888b    888  Y88b   d88P 
888 8888b 888 Y88b d88P
888 88888b 888 Y88o88P
.d88888 888 888 888Y88b 888 Y888P
d88" 888 888 .88P 888 Y88b888 888
888 888 888888K 888 Y88888 888
Y88b 888 888 "88b 888 Y8888 888
"Y88888 888 888 888 Y888 888
888
888
888
Зарегистрируйтесь для добавления материалов без проверки.