是否必须在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中。
junedkazi 2012年

1
因此,似乎没有办法避免违反DRY。可怜。
berkes 2012年

我一无所知。但是您可以编写一个具有模式定义的小函数,并在两个函数中调用该定义。
junedkazi 2012年

@berkes可以定义另一个函数,该函数返回附加模式,并在update和install挂钩中都引用它。
user1359

Answers:


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()中。换句话说:有没有办法避免违反DRY?
berkes 2012年

3
@berkes当场就......有一个很好的解释这是为什么,在这里如果你尚未看到它
克莱夫

@Clive这是一个了不起的例子。以前从未见过。+1
junedkazi 2012年

@junedkazi在您的评论中提供的链接上有一个链接;)
克莱夫(Clive

-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();
    }
  }
}


按照指示使用API​​是更好的Drupal实践。直接使用hook_schema()和hook_update_N()。我要做的一件事是在hook_update_N()中调用模块的hook_schema实现,然后运行相应的db_ *函数。
mradcliffe

hook_install()出于一个简单的事实,不应调用任何hook_update_N()实现:hook_install()用于首次安装模块,这意味着没有要更新的表。另外,您的代码不适用于需要批量运行的更新。
kiamlaluno

如果您要更新架构且仅出于部署目的,则此代码段将很有用。对于现有的实时系统,无法使用它。
Akhila V Nair
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.