You are here

使用hook_schema_alter()修改已有模式

老葛的Drupal培训班 Think in Drupal

一般来说,模块会创建和使用它们自己的数据库表。但是,如果你的模块想修改一个已有的表时,那该怎么办呢?假定你的模块需要向node表中添加一列。最简单的方式是直接访问你的数据库,在里面添加一列。但是这样以来,反映实际数据库表的模式定义就会出现不兼容的问题。这里有一个更好的方式,那就是使用hook_schema_alter()。
 
警告 hook_schema_alter()是Drupal中的新钩子,对于如何使用这个钩子,什么才是最佳的用法,还存在争论。更多详细,参看http://api.drupal.org/api/group/hooks/6
 
    假定你有一个模块,想按照某种方式来标记节点,一般来说,你可以创建一个数据库表,并使用节点ID将其与node表关联起来,但是你没有这样做,出于性能的考虑,你决定完全使用node表。这样一来,你的模块需要做两件事情:在你模块的安装过程中修改node表,并且修改模式定义以如实地反映数据库中的表结构。前者可以使用hook_install(),后者可以使用hook_schema_alter()。假定你的模块为markednode.module,那么在你的markednode.install文件中应该包含以下函数:
 
/**
 * Implementation of hook_install().
 */
function markednode_install() {
    $field = array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'initial' => 0, // Sets initial value for preexisting nodes.
        'description' => t('Whether the node has been marked by the
            markednode module.'),
    );
 
    // Create a regular index called 'marked' on the field named 'marked'.
    $keys['indexes'] = array(
        'marked' => array('marked')
    );
 
    $ret = array(); // Results of the SQL calls will be stored here.
    db_add_field($ret, 'node', 'marked', $field, $keys);
}
 
/**
 * Implementation of hook_schema_alter(). We alter $schema by reference.
 *
 * @param $schema
 * The system-wide schema collected by drupal_get_schema().
 */
function markednode_schema_alter(&$schema) {
    // Add field to existing schema.
    $schema['node']['fields']['marked'] = array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'description' => t('Whether the node has been marked by the
            markednode module.'),
    );
}

Drupal版本:

评论

tanjianfei 的头像

 这东西也太多了吧,学不完啊!真应了那句“学海无涯,苦作舟”!没有毅力是拿不下来的,坚持... ...