スキーマの管理とマイグレーション
スキーマシェルはスキーマオブジェクト、SQLダンプを作成したり、スナップショットを作成、 保存する機能を提供します。
スキーマファイルの作成と使用方法
作成したスキーマファイルを使うと、データベースに依存することなく簡単に別の環境へ移植できます。 また、既存のデータベースを使用してスキーマファイルを生成することもできます。
$ bin/cake schema generate上のコマンドで schema.php ファイルが config/Schema ディレクトリ (レガシーレイアウトでは app/Config/Schema) に生成されるはずです。
NOTE
スキーマシェルはモデルが定義されたテーブルのみを対象として処理します。 強制的に全てのテーブルを対象にするためには、 -f オプションを加える必要があります。
前もって作成した schema.php からデータベースを再構築するためには、次のコマンドを実行してください。
$ bin/cake schema createschema.php の中身に沿ってテーブルが再構成されるはずです。
スキーマファイルは SQL ダンプファイルの作成に使用することもできます。 CREATE TABLE 文を含む SQL ファイルを生成するには次のコマンドを実行してください。
$ bin/cake schema dump --write filename.sqlここで filename.sql には SQL ファイルとして出力したいファイル名を指定します。 filename.sql を省略すると、SQL のダンプはコンソールへ出力されますが、 ファイルへ出力されることはありません。
CakeSchema のコールバック
スキーマの生成後、アプリケーションを動作させるためテーブルにデータを挿入したいと 考えるかもしれません。データも CakeSchema のコールバックで保存させることができます。 全てのスキーマファイルは before($event = []) メソッドと after($event = []) メソッドが生成されます。
$event パラメータは2つのキーを持つ配列です。1つはテーブルを削除するのか 作成するのかを示すパラメータで、もう1つはエラーに関するパラメータです。例を示します。
['drop' => 'posts', 'errors' => null]
['create' => 'posts', 'errors' => null]データを posts テーブルへ加える例は以下のようになります。
App::uses('Post', 'Model');
public function after($event = [])
{
if (isset($event['create'])) {
switch ($event['create']) {
case 'posts':
App::uses('ClassRegistry', 'Utility');
$post = ClassRegistry::init('Post');
$post->create();
$post->save([
'Post' => ['title' => 'CakePHP Schema Files'],
]);
break;
}
}
}ここでコールバック before() および after() は、 スキーマからテーブルが作成されるか削除されるたびに実行されます。
データを2つ以上のテーブルへ挿入する場合は、各テーブルの作成後、 データベースのキャッシュを実際にデータベースへ反映させる必要があるでしょう。 before アクション内で $db->cacheSources = false を設定することにより、 キャッシュを無効にできます。
public $connection = 'default';
public function before($event = [])
{
$db = ConnectionManager::getDataSource($this->connection);
$db->cacheSources = false;
return true;
}コールバック中に正しいデータソースで初期化したモデルを使用したい場合、 デフォルトのデータソースを使わないようにします。
public function before($event = [])
{
$articles = ClassRegistry::init('Articles', [
'ds' => $this->connection,
]);
// Do things with articles.
}CakePHP スキーマを手書きする
CakeSchema クラスは、全てのデータベーススキーマの基本クラスです。それぞれの スキーマクラスはテーブルのセットを生成することができます。 スキーマシェルコンソールクラス SchemaShell は、コマンドラインを解釈し、基本スキーマクラスは、データベースからの 読み込みやデータベーステーブルの生成ができます。
CakeSchema は、プラグインへのスキーマファイルを配置・読み込み・書き込みができます。 SchemaShell もまた、その機能を持っています。
CakeSchema はまた、 tableParameters をサポートします。 テーブルパラメータは、照合順序、キャラセット、コメント文、エンジンタイプのような、 カラム以外のテーブル情報です。それぞれの Dbo は、サポートする tableParameters を実装します。
例
以下は acl クラスの例全部です。
/**
* ACO - Access Control Object - Something that is wanted
*/
public $acos = [
'id' => [
'type' => 'integer',
'null' => false,
'default' => null,
'length' => 10,
'key' => 'primary',
],
'parent_id' => [
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10,
],
'model' => ['type' => 'string', 'null' => true],
'foreign_key' => [
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10,
],
'alias' => ['type' => 'string', 'null' => true],
'lft' => [
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10,
],
'rght' => [
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10,
],
'indexes' => ['PRIMARY' => ['column' => 'id', 'unique' => 1]],
];カラム
それぞれのカラムは、キーバリュー連想配列として表現されます。 フィールド名は、フィールドのキーです。値は、いくつかの属性を持つ別の配列です。
カラムの例:
'id' => [
'type' => 'integer',
'null' => false,
'default' => null,
'length' => 10,
'key' => 'primary'
],keyprimary キーは、主キーインデックスを定義します。
null
フィールドが null を許可するかどうか。
default
フィールドのデフォルト値。
limit
フィールドの型の限界。
length
フィールドの長さ。
type
以下の型の一つ
- integer
- smallinteger
- tinyinteger
- biginteger
- date
- time
- datetime
- timestamp
- boolean
- float
- string
- text
- binary
Changed in version 2.10.0
smallinteger 型と tinyinteger 型は 2.10.0 で追加されました。
テーブルキー indexes
キー名 indexes は、フィールド名の代わりにテーブル配列の中に置きます。
column
これは単一のカラム名またはカラムの配列です。
単一の場合:
'indexes' => [
'PRIMARY' => [
'column' => 'id',
'unique' => 1
]
]複数の場合:
'indexes' => [
'AB_KEY' => [
'column' => [
'a_id',
'b_id'
],
'unique' => 1
]
]unique
ユニークインデックスなら 1、そうでなければ 0。
テーブルキー tableParameters
tableParameters は、 MySQL のみサポートします。
tableParameters を使って、いろいろな MySQL 特有の設定をセットすることができます。
engineは、テーブルで使用するストレージエンジンを制御します。charsetは、テーブルで使用するキャラクターセットを制御します。encodingは、テーブルで使用する文字コードを制御します。
MySQL の dbo は、 tableParameters に加えて fieldParameters を実装します。 fieldParameters は、 MySQL 特有の設定をカラムごとに制御することができます。
charsetは、カラムで使用するキャラクターセットを設定します。encodingは、カラムで使用する文字コードを設定します。
スキーマファイルの中でテーブルやフィールドのパラメータを使用する方法は、 下記の例をご覧ください。
スキーマファイルの中で tableParameters を使う
スキーマファイル中の他のキーと同じように tableParameters が使えます。 例えば indexes のように:
public $comments = [
'id' => [
'type' => 'integer',
'null' => false,
'default' => 0,
'key' => 'primary',
],
'post_id' => ['type' => 'integer', 'null' => false, 'default' => 0],
'comment' => ['type' => 'text'],
'indexes' => [
'PRIMARY' => ['column' => 'id', 'unique' => true],
'post_id' => ['column' => 'post_id'],
],
'tableParameters' => [
'engine' => 'InnoDB',
'charset' => 'latin1',
'collate' => 'latin1_general_ci',
],
];いくつかのデータベース特有の設定をセットするために tableParameters を 使用しているテーブルの例です。もしデータベースが実装していないオプションや 機能を含むスキーマファイルを使用した時、オプションは無視されます。
CakePHP のスキーマシェルを使ったマイグレーション
マイグレーションで、スキーマのバージョン管理ができるようになります。 その結果、新機能を開発したとき、データベースに依存することなく簡単に 変更内容を配布できるようになります。マイグレーションはバージョン管理された スキーマファイルかスキーマのスナップショットのどちらかの形式で管理されます。 スキーマシェルを使ったスキーマファイルのバージョン管理はとても簡単です。 もし既に作成済みのスキーマファイルがあるのであれば、次のコマンドを実行してください。
$ bin/cake schema generate実行すると、次の選択肢が表示されるはずです。
Generating Schema...
Schema file exists.
[O]verwrite
[S]napshot
[Q]uit
Would you like to do? (o/s/q)[s] (snapshot) を選択すると、変更分を反映した schema.php が生成されるでしょう。 もし schema.php があれば、schema_2.php あるいは同様のファイルが生成されるはずです。 いつでも以下のコマンドでスキーマファイルへの保存ができます。
$ bin/cake schema update -s 2ここで 2 は更新元のスナップショット番号を示します。 スキーマシェルは、現状のデータベースと更新元スキーマファイルの差分を表した ALTER 文を実行してもよいかどうか確認を促してくるでしょう。
--dry コマンドを付けることで、実際にファイルを更新することなく実行結果だけを 確認することもできます(dry-run)。
NOTE
2.x のスキーマ生成は外部キー制約を処理しないことに注意してください。
ワークフローの例
スキーマの生成とコミット
バージョン管理を適用しているプロジェクトでは、cake schema を以下のように使うことになるでしょう。
データベース内のテーブルを生成あるいは変更
cake schema を実行し、データベースの内容を全てエクスポート
生成または更新された schema.php のコミット:
$ # 一度データベースを更新した後で $ bin/cake schema generate $ git commit -a
NOTE
プロジェクトでバージョン管理システムを使用していない場合は、 スキーマの管理はスナップショットを使用して行うことになるはずです。 (スナップショットの作成は前のセクションを参照してください)
最新の変更を取り入れるには
(テーブルが見つからないというエラーメッセージが表示された場合など) リポジトリの最新の変更を取り入れ、データベース構造の変更点を見つけるには 以下のようにします。
cake schema を実行し、データベースを更新してください:
$ git pull $ bin/cake schema create $ bin/cake schema update
いずれの操作でも --dry オプションで dry-run が使用できます。
ロールバック
現在のところ、cake schema はデータベースの更新の取り消しや復元が必要な操作をサポートしていません。
より具体的には、一度生成したテーブルを自動的に削除することができないようになっています。
対照的に update を使用した場合は、スキーマファイルとの差分からフィールドが削除されます。
$ git revert HEAD
$ bin/cake schema update上のコマンドを実行すると、以下の選択肢が表示されるはずです。
The following statements will run.
ALTER TABLE `roles`
DROP `position`;
Are you sure you want to alter the tables? (y/n)
[n] >