最近はHTTP Cacheまわりにかなり興味がでてきたので、久しぶりにBEAR.Sundayを触っています。
全く持って覚えてなかったので、素振りをしようと思ってとりあえずチケットチュートリアルをやりました。
無事に素振りが終わって実際に趣味のアプリケーションのコードを書き始めようと思いましたが、データベースのマイグレーションツールをどうしようか悩みました。
チケットチュートリアルでは、データベースのマイグレーションにphinxを使っています。
特にphinxに不満はありませんが、なんとなく他になに違うツールはないかと調べてみました。
Doctrine MigrationsはDoctrineを利用していなくても使える
調べていくうちに、Doctrine MigrationsがDoctrineを利用していなくても使えることが書かれたzennの記事に遭遇しました。
PHPで「Doctrine Migrations」を使ってみる
本当に素晴らしい記事ですね!Symfonyユーザーの自分はDoctrine MigrationsがDoctrineを利用していなくても使えるなんて知りませんでした。
(普段からSymfony + Doctrineで開発しているから逆に気づかないやつですね。)
というとでBEAR.SundayでDoctrine Migrationsを使うことにしました。
まずはBEAR.Sundayでプロジェクトを作る
まずはBEAR.Sundayでプロジェクトを作ります。
1
|
$ composer create-project bear/skeleton Polidog.DoctrineMigrationExample
|
Doctrine Migrationsのパッケージをインストールする
次にDoctrine Migrationのパッケージをインストールします。
1
|
$ composer req --dev doctrine/migrations
|
データベースをdocker composeで用意する
compose.yamlを用意します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
services:
database:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: example_db
MYSQL_USER: docker
MYSQL_PASSWORD: docker
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
|
用意できたらコンテナを起動しておきます。
1
2
|
$ docker compose up -d
✔ Container polidogdoctrinemigrationexample-database-1 Started
|
問題なく起動できるかと思います。
envファイルについて
データベース接続情報を管理するのにDotenvを使います。
1
2
3
4
5
6
7
|
DB_NAME=example_db
DB_USER=root
DB_PASSWORD=root
DB_HOST=0.0.0.0
DB_PORT=3306
DB_DRIVER=pdo_mysql
DB_DSN=mysql:dbname=${DB_NAME};host=${DB_HOST};port=${DB_PORT}
|
必要なファイルとディレクトリ構成について
今回は設定ファイルやマイグレーションファイルは var/doctrine
のディレクトリ化に配置するようにします。
DoctrineMigrationsではマイグレーション用の設定ファイルと、データベースコネクション用のファイルを用意します。
今回はphpファイルで用意しますが、yamlでも設定することは可能です。
まずはmigration.phpを用意する
var以下にディレクトリを用意します。
1
|
$ mkdir -p var/doctrine/migrations
|
次に var/doctrine
に移動し、migrations.phpを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
// var/doctrine/migrations.php
return [
'table_storage' => [
'table_name' => 'doctrine_migration_versions',
'version_column_name' => 'version',
'version_column_length' => 191,
'executed_at_column_name' => 'executed_at',
'execution_time_column_name' => 'execution_time',
],
'migrations_paths' => [
'Polidog\\DoctrineMigrationExample\\Migrations' => __DIR__ . '/migrations'
],
'all_or_nothing' => true,
'transactional' => true,
'check_database_platform' => true,
'organize_migrations' => 'year_and_month',
'connection' => null,
'em' => null,
];
|
migrations-db.phpとmigrations-db-test.phpを用意する
データベース接続用のファイルを2つ用意します。
通常用に migrations-db.php
, テスト用には migrations-db-test.php
を使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// var/doctrine/migrations-db.php
<?php
use BEAR\Dotenv\Dotenv;
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
(new Dotenv())->load(dirname(__DIR__, 2));
return [
'dbname' => getenv('DB_NAME'),
'user' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'host' => getenv('DB_HOST'),
'port' => getenv('DB_PORT'),
'driver' => getenv('DB_DRIVER')
];
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
// var/doctrine/migrations-db-test.php
use BEAR\Dotenv\Dotenv;
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
(new Dotenv())->load(dirname(__DIR__, 2));
return [
'dbname' => getenv('DB_NAME') . '_test',
'user' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'host' => getenv('DB_HOST'),
'port' => getenv('DB_PORT'),
'driver' => getenv('DB_DRIVER')
];
|
マイグレーションファイルを生成する
ここまで設定が完了したらマイグレーションファイルを生成します。
デフォルトの設定ファイル、DB接続ファイルの位置とは違うので、configuration
, db-configuration
のオプションを指定する必要があります。
1
|
$ vendor/bin/doctrine-migrations migrations:generate --configuration=var/doctrine/migrations.php --db-configuration=var/doctrine/migration-db.php
|
実行することでvar/doctrine/migrations/{year}/{month}/VersionXXXXXX.php
というファイルが生成されているかと思います。
今回の自分の環境だと ``var/doctrine/migrations/2024/03/Version20240312153132.php` が生成されました。
中身は以下のようになっています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?php
declare(strict_types=1);
namespace Polidog\DoctrineMigrationExample\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240312153132 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
}
}
|
試しにユーザーテーブルを作るコードを書いてみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
<?php
declare(strict_types=1);
namespace Polidog\DoctrineMigrationExample\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240312153132 extends AbstractMigration
{
public function getDescription(): string
{
return 'Create user table';
}
public function up(Schema $schema): void
{
$table = $schema->createTable('users');
$table->addColumn('id', 'integer', ['autoincrement' => true]);
$table->addColumn('username', 'string', ['length' => 255]);
$table->addColumn('avatar_url', 'string', [
'length' => 255,
'notnull' => true,
'default' => null
]);
$table->addColumn("created_at", "datetime", [
"notnull" => false,
"default" => null
]);
$table->addColumn("updated_at", "datetime", [
"notnull" => false,
"default" => null
]);
$table->setPrimaryKey(['id']);
}
public function down(Schema $schema): void
{
$schema->dropTable("authors");
}
}
|
ファイルが用意できたら次にmigrationを実行してみましょう。
1
|
$ vendor/bin/doctrine-migrations migrations:migrate --configuration=var/doctrine/migrations.php --db-configuration=var/doctrine/migration-db.php
|
これでテーブルが作成されていると思います。
composer scriptsにmigrate, generateコマンドを定義する
マイグレーションファイルの生成、適用は毎回手で入力するとめんどくさいのでcomposer scriptsに定義すると便利です。
1
2
3
|
...
"migrations:generate": "vendor/bin/doctrine-migrations migrations:generate --configuration=var/doctrine/migrations.php --db-configuration=var/doctrine/migrations-db.php",
"migrations:migrate": "vendor/bin/doctrine-migrations migrations:migrate --configuration=var/doctrine/migrations.php --db-configuration=var/doctrine/migrations-db.php"
|
定義できたら以下のようにコマンドが使えるようになります。
1
2
|
$ composer migrations:generate
$ composer migrations:migrate
|
bin/setup.phpを活用する
BEAR.Sundayではプロジェクト生成時に bin/setup.php
が生成されます。
チケットチュートリアルでも使っていましたが、マイグレーションやデータベースの生成はsetupで定義すると便利です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php
// bin/setup.php
declare(strict_types=1);
use BEAR\Dotenv\Dotenv;
require_once dirname(__DIR__) . '/vendor/autoload.php';
(new Dotenv())->load(dirname(__DIR__));
chdir(dirname(__DIR__));
passthru('rm -rf ./var/tmp/*');
// データベースの作成
$pdo = new \PDO(getenv('DB_DSN'), getenv('DB_USER'), getenv('DB_PASSWORD'));
$pdo->exec('CREATE DATABASE IF NOT EXISTS ' . getenv('DB_NAME'));
$pdo->exec('DROP DATABASE IF EXISTS ' . getenv('DB_NAME') . '_test');
$pdo->exec('CREATE DATABASE ' . getenv('DB_NAME') . '_test');
// migrationの実行
$migrationsConfigPath = dirname(__DIR__) . '/var/doctrine/migrations.php';
$dbConfigPath = dirname(__DIR__) . '/var/doctrine/migrations-db.php';
$dbConfigTestPath = dirname(__DIR__) . '/var/doctrine/migrations-db-test.php';
passthru("vendor/bin/doctrine-migrations migrations:migrate --configuration=$migrationsConfigPath --db-configuration=$dbConfigPath --no-interaction ");
passthru("vendor/bin/doctrine-migrations migrations:migrate --configuration=$migrationsConfigPath --db-configuration=$dbConfigTestPath --no-interaction ");
|
このように定義できたら以下のコマンドを実行します。
もしくは以下のコマンドでも大丈夫です。
今回のサンプルコードについて
Github上でコードを公開しています。
polidog/Polidog.DoctrineMigrationExample
最後に
今回はBEAR.SundayでDoctrine Migrationsを使う方法をご紹介しました。
この個人ブログをBEAR.Sundayで作り直そうと思っているので、今後も何かしらのBEAR.Sundayを使った知見を共有できればと考えています。
この記事を読んだ皆さんもぜひBEAR.Sundayを触ってみてください。きっと好きになります。
参考記事