2019/8/5 追記:hook_post_update_NAME()ではなく、hook_update_N()を使用するように変更しました。
はじめに
使用しているカスタムモジュールに機能追加した場合、使用しているDBテーブルの定義を変更する必要が出てきたりします。
Drupalでは「モジュールのアップデート」でDB定義を変更することができるようなので、その方法を試してみます。
1. 前提(環境情報)
- Drupal: 8.7
- PHP: 7.2
- そのほかDB,webサーバなどはよしなに...
また、カスタムモジュールとして"sample"という名前のモジュールがインストールされており、
sample.installにて以下のDBテーブルが定義されているものとします。
<?php
・
・
・
function sample_schema(){
$schema['sample_greeting'] = [
'description' => 'greeting messages',
'fields' => [
'id' => [
'description' => 'identifier',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'message_text' => [
'description' => 'greeting message',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
],
],
'primary key' => [
'id',
],
];
return $schema;
}
・
・
・
上記テーブルには、レコードが存在するものとします。
mysql> select * from sample_greeting;
+----+--------------+
| id | message_text |
+----+--------------+
| 1 | Bonjour |
| 2 | Hujambo |
| 3 | konnichiwa |
| 4 | Hi there |
+----+--------------+
それでは、上記のテーブルににnationalityカラムを追加してみます。
2. モジュールの修正
追加カラムの定義をsample.installに追記する。
<?php
・
・
・
function sample_schema(){
$schema['sample_greeting'] = [
'description' =--> 'greeting messages',
'fields' => [
'id' => [
'description' => 'identifier',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'message_text' => [
'description' => 'greeting message',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
],
//追加カラム
'nationality' => [
'description' => 'nationality',
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
],
],
'primary key' => [
'id',
],
];
return $schema;
}
・
・
・
続けて同ファイルにhook_post_update_Nを実装し、
テーブル定義を変更するコードを記述する。
/**
* Add a nationality column to the sample_greeting table.
*/
function sample_update_8101() {
//Nの部分は、以下の数字を組み合わせた4または5桁の数字に置き換える
//上位桁から順番に
// 1桁、または2桁のDrupalのcoreバージョン(8,9,10など)を表す数字
// 1桁のカスタムモジュールのバージョンを表す数字(8.x-1.*なら1,8.x-2.*なら2といった具合)
// 2桁の通し番号。(01からカウントアップ)
//となる。
$specification = [
'description' => 'nationality',
'type' => 'varchar',
'length' => 255,
'not null' => FALSE
];
$schema = Database::getConnection()->schema();
$schema->addField('sample_greeting', 'nationality', $specification);
}
sample.info.ymlに記載しているモジュールバージョンの変更
name: sample
type: module
description: sample
core: 8.x
package: sample
#1.0 -> 1.1に
version: '8.x-1.1'
core: '8.x'
3. update.phpの実行
update.phpにブラウザでアクセスし、[継続]。
更新内容が表示されるので、[保留中のアップデートを適用する]。
適用完了。
4. 確認
既存レコードを壊さずに、カラムの追加ができた。
mysql> select * from sample_greeting;
+----+--------------+-------------+
| id | message_text | nationality |
+----+--------------+-------------+
| 1 | Bonjour | NULL |
| 2 | Hujambo | NULL |
| 3 | konnichiwa | NULL |
| 4 | Hi there | NULL |
+----+--------------+-------------+
4 rows in set (0.00 sec)
その他注意点など
・似たようなことができるhookとしてhook_post_update_NAME()というのがある。
hook_post_update_NAME()が呼び出されるのは実装されたhook_update_N()が全て実行された後。
また、このhookはEntityの更新に使うことが主な目的のため、今回のようにモジュールのアップデート目的で使うべきではないようです。
参考
- コメントを追加
- 閲覧数 268
いくつか
コメントありがとうございます
ご指摘の通り、誤記を修正しました。
hook_update_N()についても追加で調べてみます。
コメントを追加