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

Вот столкнулся с задачей: есть модуль, к которому необходимо написать обновление так, чтобы в следующей версии была добавлена новая таблица в базе данных. 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  8888888888   .d888 
888 888 888 d88P"
888 888 888 888
888 888 Y88b d88P 8888888 888888
`Y8bd8P' Y88b d88P 888 888
X88K Y88o88P 888 888
.d8""8b. Y888P 888 888
888 888 Y8P 888 888


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